From e465e1a54e5d1e72b58d2bc46a0f89c8bfb71469 Mon Sep 17 00:00:00 2001
From: VIRUSPARTH
Date: Tue, 29 Oct 2024 00:17:17 +0530
Subject: [PATCH] new changes
---
backend/.env | 4 +-
backend/Dockerfile | 15 +
backend/package-lock.json | 109 ++-
backend/package.json | 7 +-
.../appControllers/clientController/create.js | 91 +++
.../appControllers/clientController/index.js | 17 +-
.../clientController/listAll.js | 30 +
.../clientController/migrate.js | 16 +
.../clientController/paginatedList.js | 67 ++
.../appControllers/clientController/read.js | 29 +
.../appControllers/clientController/remove.js | 84 ++
.../appControllers/clientController/search.js | 51 ++
.../appControllers/clientController/update.js | 12 +
.../appControllers/companyController/index.js | 24 +
.../companyController/remove.js | 57 ++
.../companyController/update.js | 44 +
.../invoiceController/remove.js | 29 +-
.../invoiceController/update.js | 69 +-
.../appControllers/leadController/create.js | 51 ++
.../appControllers/leadController/index.js | 29 +
.../appControllers/leadController/listAll.js | 30 +
.../appControllers/leadController/migrate.js | 18 +
.../leadController/paginatedList.js | 68 ++
.../appControllers/leadController/read.js | 29 +
.../appControllers/leadController/remove.js | 10 +
.../appControllers/leadController/search.js | 50 ++
.../appControllers/leadController/summary.js | 97 +++
.../appControllers/leadController/update.js | 13 +
.../appControllers/offerController/create.js | 61 ++
.../appControllers/offerController/index.js | 18 +
.../offerController/paginatedList.js | 68 ++
.../appControllers/offerController/read.js | 30 +
.../offerController/sendMail.js | 9 +
.../appControllers/offerController/summary.js | 123 +++
.../appControllers/offerController/update.js | 10 +
.../paymentController/remove.js | 63 +-
.../paymentController/update.js | 81 +-
.../appControllers/peopleController/index.js | 21 +
.../peopleController/paginatedList.js | 64 ++
.../appControllers/peopleController/read.js | 26 +
.../appControllers/peopleController/remove.js | 8 +
.../appControllers/peopleController/update.js | 13 +
.../appControllers/quoteController/update.js | 57 +-
.../appControllers/taxesController/index.js | 37 +-
.../coreControllers/emailController/index.js | 14 +
.../settingController/updateBySettingKey.js | 50 +-
.../settingController/updateManySetting.js | 59 +-
.../createAuthMiddleware/authUser.js | 50 +-
.../createAuthMiddleware/forgetPassword.js | 7 +
.../createAuthMiddleware/index.js | 6 +
.../createAuthMiddleware/isValidAuthToken.js | 10 +-
.../createAuthMiddleware/login.js | 15 +-
.../createAuthMiddleware/logout.js | 48 +-
.../createAuthMiddleware/register.js | 84 ++
.../createAuthMiddleware/resetPassword.js | 71 +-
.../createAuthMiddleware/sendIdurarOffer.js | 18 +
.../createAuthMiddleware/sendMail.js | 7 +-
.../createCRUDController/remove.js | 33 +-
.../createCRUDController/update.js | 31 +-
.../createUserController/updatePassword.js | 8 -
.../createUserController/updateProfile.js | 9 -
.../updateProfilePassword.js | 7 -
backend/src/emailTemplate/emailVerfication.js | 72 +-
backend/src/locale/languages.js | 63 +-
backend/src/locale/translation/en_us.js | 2 +-
backend/src/middlewares/rateLimiter.js | 53 ++
backend/src/models/appModels/Client.js | 16 +-
backend/src/models/appModels/Company.js | 217 +++++
backend/src/models/appModels/Employee.js | 186 +++++
backend/src/models/appModels/Expense.js | 98 +++
.../src/models/appModels/ExpenseCategory.js | 39 +
backend/src/models/appModels/Lead.js | 92 +++
backend/src/models/appModels/Offer.js | 135 ++++
backend/src/models/appModels/Order.js | 140 ++++
backend/src/models/appModels/People.js | 203 +++++
backend/src/models/appModels/Product.js | 102 +++
.../src/models/appModels/ProductCategory.js | 76 ++
backend/src/models/appModels/Purchase.js | 153 ++++
backend/src/models/appModels/Shipment.js | 119 +++
backend/src/models/coreModels/Email.js | 47 ++
backend/src/routes/appRoutes/appApi.js | 2 +-
backend/src/routes/coreRoutes/coreApi.js | 11 +
backend/src/routes/coreRoutes/coreAuth.js | 5 +-
.../src/routes/coreRoutes/corePublicRouter.js | 5 +-
backend/src/server.js | 20 +-
.../setup/defaultSettings/emailSettings.json | 20 +
.../defaultSettings/inventorySettings.json | 38 +
.../setup/defaultSettings/leadSettings.json | 85 ++
.../setup/defaultSettings/offerSettings.json | 34 +
backend/src/setup/emailTemplate/index.json | 51 ++
backend/src/setup/reset.js | 4 -
backend/src/utils/redis.js | 9 +
frontend/Dockerfile | 16 +
frontend/index.html | 7 +-
frontend/package-lock.json | 753 +++++++++---------
frontend/package.json | 12 +-
frontend/src/apps/ErpApp.jsx | 29 +-
frontend/src/apps/Header/HeaderContainer.jsx | 9 +-
frontend/src/apps/Header/UpgradeButton.jsx | 79 +-
frontend/src/apps/Navigation/AppNav.jsx | 128 +++
frontend/src/apps/Navigation/ExpensesNav.jsx | 167 ++++
.../apps/Navigation/NavigationContainer.jsx | 94 ++-
.../src/components/ChooseCurrency/index.jsx | 92 +++
.../src/components/DataTable/DataTable.jsx | 6 +-
frontend/src/components/PageLoader/index.jsx | 5 +-
.../components/PaypalButton/Subscription.jsx | 38 +
frontend/src/components/SelectAsync/index.jsx | 4 +-
frontend/src/components/SelectTag/index.jsx | 8 +-
frontend/src/forms/DynamicForm/index.jsx | 5 +-
frontend/src/forms/LoginForm.jsx | 19 +-
frontend/src/forms/RegisterForm.jsx | 23 +
frontend/src/layout/AuthLayout/index.jsx | 8 +-
frontend/src/layout/ErpLayout/index.jsx | 4 +
frontend/src/locale/Localization.jsx | 5 +-
frontend/src/locale/translation/en_us.js | 4 +-
frontend/src/locale/useLanguage.jsx | 63 +-
.../modules/AdvancedCrudModule/CreateItem.jsx | 95 +++
.../modules/AdvancedCrudModule/DataTable.jsx | 194 +++++
.../modules/AdvancedCrudModule/DeleteItem.jsx | 59 ++
.../modules/AdvancedCrudModule/ItemRow.jsx | 121 +++
.../modules/AdvancedCrudModule/ReadItem.jsx | 315 ++++++++
.../modules/AdvancedCrudModule/SearchItem.jsx | 96 +++
.../modules/AdvancedCrudModule/UpdateItem.jsx | 175 ++++
.../src/modules/AdvancedCrudModule/index.jsx | 35 +
.../src/modules/AuthModule/SideContent.jsx | 99 ++-
.../components/CustomerPreviewCard.jsx | 28 +-
.../components/PreviewCard.jsx | 17 +-
.../src/modules/DashboardModule/index.jsx | 27 +-
.../EmailDataTableModule/index.jsx | 10 +
.../ReadEmailModule/components/ReadItem.jsx | 102 +++
.../EmailModule/ReadEmailModule/index.jsx | 39 +
.../componenets/EmailForm.jsx | 55 ++
.../EmailModule/UpdateEmailModule/index.jsx | 49 ++
.../src/modules/ErpPanelModule/CreateItem.jsx | 5 +-
.../src/modules/ErpPanelModule/DataTable.jsx | 5 +-
.../src/modules/ErpPanelModule/ReadItem.jsx | 11 +-
.../src/modules/ErpPanelModule/UpdateItem.jsx | 9 +-
.../InvoiceModule/ReadInvoiceModule/index.jsx | 9 +
.../components/Payment.jsx | 18 +-
.../OfferModule/CreateOfferModule/index.jsx | 11 +
.../modules/OfferModule/Forms/OfferForm.jsx | 290 +++++++
.../OfferDataTableModule/index.jsx | 10 +
.../ReadOfferModule/ReadOfferItem.jsx | 318 ++++++++
.../OfferModule/ReadOfferModule/index.jsx | 40 +
.../OfferModule/UpdateOfferModule/index.jsx | 50 ++
.../OrderModule/CreateOrderModule/index.jsx | 11 +
.../modules/OrderModule/Forms/InvoiceForm.jsx | 284 +++++++
.../OrderDataTableModule/index.jsx | 22 +
.../OrderModule/ReadOrderModule/index.jsx | 39 +
.../components/Payment.jsx | 140 ++++
.../components/RecordPayment.jsx | 73 ++
.../OrderModule/RecordPaymentModule/index.jsx | 37 +
.../OrderModule/UpdateInvoiceModule/index.jsx | 50 ++
.../ReadPaymentModule/components/ReadItem.jsx | 8 +-
.../components/Payment.jsx | 12 +-
.../modules/QuoteModule/Forms/QuoteForm.jsx | 9 +-
.../CompanySettingsModule/SettingsForm.jsx | 4 +-
.../FinanceSettingsModule/SettingsForm.jsx | 30 +-
.../forms/GeneralSettingForm.jsx | 77 +-
.../SettingsForm.jsx | 7 +-
.../components/SetingsSection.jsx | 5 +-
.../components/UpdateSettingModule.jsx | 7 +
frontend/src/pages/AdvancedSettings/index.jsx | 102 +++
frontend/src/pages/Company/config.js | 173 ++++
frontend/src/pages/Company/index.jsx | 39 +
frontend/src/pages/Customer/config.js | 43 +-
frontend/src/pages/Email/EmailRead.jsx | 21 +
frontend/src/pages/Email/EmailUpdate.jsx | 22 +
frontend/src/pages/Email/index.jsx | 63 ++
frontend/src/pages/Employee/index.jsx | 125 +++
frontend/src/pages/Expense/config.js | 25 +
frontend/src/pages/Expense/index.jsx | 39 +
frontend/src/pages/ExpenseCategory/config.js | 21 +
frontend/src/pages/ExpenseCategory/index.jsx | 39 +
frontend/src/pages/Inventory/index.jsx | 71 ++
frontend/src/pages/Invoice/index.jsx | 24 +
frontend/src/pages/Lead/config.js | 90 +++
frontend/src/pages/Lead/index.jsx | 39 +
frontend/src/pages/Login.jsx | 67 +-
frontend/src/pages/Offer/OfferCreate.jsx | 20 +
frontend/src/pages/Offer/OfferRead.jsx | 20 +
frontend/src/pages/Offer/OfferUpdate.jsx | 20 +
frontend/src/pages/Offer/index.jsx | 102 +++
frontend/src/pages/Order/index.jsx | 97 +++
frontend/src/pages/People/config.js | 94 +++
frontend/src/pages/People/index.jsx | 39 +
frontend/src/pages/Product/config.js | 25 +
frontend/src/pages/Product/index.jsx | 39 +
frontend/src/pages/ProductCategory/config.js | 21 +
frontend/src/pages/ProductCategory/index.jsx | 39 +
frontend/src/pages/Quote/index.jsx | 10 +
frontend/src/pages/Register.jsx | 60 ++
frontend/src/redux/rootReducer.js | 2 +
frontend/src/redux/store.js | 23 +-
frontend/src/redux/translate/actions.js | 41 +
frontend/src/redux/translate/index.js | 1 +
frontend/src/redux/translate/reducer.js | 47 ++
frontend/src/redux/translate/selectors.js | 10 +
frontend/src/redux/translate/types.js | 5 +
frontend/src/request/errorHandler.js | 17 +-
frontend/src/request/request.js | 38 +-
frontend/src/router/AuthRouter.jsx | 2 +
frontend/src/router/routes.jsx | 76 +-
frontend/src/style/partials/collapseBox.css | 2 +-
frontend/src/style/partials/core.css | 5 +-
frontend/src/style/partials/customAntd.css | 27 +-
frontend/src/style/partials/navigation.css | 8 +-
frontend/src/style/partials/rest.css | 2 +-
frontend/src/utils/countryList.js | 199 ++++-
209 files changed, 10003 insertions(+), 1239 deletions(-)
create mode 100644 backend/Dockerfile
create mode 100644 backend/src/controllers/appControllers/clientController/create.js
create mode 100644 backend/src/controllers/appControllers/clientController/listAll.js
create mode 100644 backend/src/controllers/appControllers/clientController/migrate.js
create mode 100644 backend/src/controllers/appControllers/clientController/paginatedList.js
create mode 100644 backend/src/controllers/appControllers/clientController/read.js
create mode 100644 backend/src/controllers/appControllers/clientController/remove.js
create mode 100644 backend/src/controllers/appControllers/clientController/search.js
create mode 100644 backend/src/controllers/appControllers/clientController/update.js
create mode 100644 backend/src/controllers/appControllers/companyController/index.js
create mode 100644 backend/src/controllers/appControllers/companyController/remove.js
create mode 100644 backend/src/controllers/appControllers/companyController/update.js
create mode 100644 backend/src/controllers/appControllers/leadController/create.js
create mode 100644 backend/src/controllers/appControllers/leadController/index.js
create mode 100644 backend/src/controllers/appControllers/leadController/listAll.js
create mode 100644 backend/src/controllers/appControllers/leadController/migrate.js
create mode 100644 backend/src/controllers/appControllers/leadController/paginatedList.js
create mode 100644 backend/src/controllers/appControllers/leadController/read.js
create mode 100644 backend/src/controllers/appControllers/leadController/remove.js
create mode 100644 backend/src/controllers/appControllers/leadController/search.js
create mode 100644 backend/src/controllers/appControllers/leadController/summary.js
create mode 100644 backend/src/controllers/appControllers/leadController/update.js
create mode 100644 backend/src/controllers/appControllers/offerController/create.js
create mode 100644 backend/src/controllers/appControllers/offerController/index.js
create mode 100644 backend/src/controllers/appControllers/offerController/paginatedList.js
create mode 100644 backend/src/controllers/appControllers/offerController/read.js
create mode 100644 backend/src/controllers/appControllers/offerController/sendMail.js
create mode 100644 backend/src/controllers/appControllers/offerController/summary.js
create mode 100644 backend/src/controllers/appControllers/offerController/update.js
create mode 100644 backend/src/controllers/appControllers/peopleController/index.js
create mode 100644 backend/src/controllers/appControllers/peopleController/paginatedList.js
create mode 100644 backend/src/controllers/appControllers/peopleController/read.js
create mode 100644 backend/src/controllers/appControllers/peopleController/remove.js
create mode 100644 backend/src/controllers/appControllers/peopleController/update.js
create mode 100644 backend/src/controllers/coreControllers/emailController/index.js
create mode 100644 backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js
create mode 100644 backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendIdurarOffer.js
create mode 100644 backend/src/middlewares/rateLimiter.js
create mode 100644 backend/src/models/appModels/Company.js
create mode 100644 backend/src/models/appModels/Employee.js
create mode 100644 backend/src/models/appModels/Expense.js
create mode 100644 backend/src/models/appModels/ExpenseCategory.js
create mode 100644 backend/src/models/appModels/Lead.js
create mode 100644 backend/src/models/appModels/Offer.js
create mode 100644 backend/src/models/appModels/Order.js
create mode 100644 backend/src/models/appModels/People.js
create mode 100644 backend/src/models/appModels/Product.js
create mode 100644 backend/src/models/appModels/ProductCategory.js
create mode 100644 backend/src/models/appModels/Purchase.js
create mode 100644 backend/src/models/appModels/Shipment.js
create mode 100644 backend/src/models/coreModels/Email.js
create mode 100644 backend/src/setup/defaultSettings/emailSettings.json
create mode 100644 backend/src/setup/defaultSettings/inventorySettings.json
create mode 100644 backend/src/setup/defaultSettings/leadSettings.json
create mode 100644 backend/src/setup/defaultSettings/offerSettings.json
create mode 100644 backend/src/setup/emailTemplate/index.json
create mode 100644 backend/src/utils/redis.js
create mode 100644 frontend/Dockerfile
create mode 100644 frontend/src/apps/Navigation/AppNav.jsx
create mode 100644 frontend/src/apps/Navigation/ExpensesNav.jsx
create mode 100644 frontend/src/components/ChooseCurrency/index.jsx
create mode 100644 frontend/src/components/PaypalButton/Subscription.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/CreateItem.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/DataTable.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/DeleteItem.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/ItemRow.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/ReadItem.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/SearchItem.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/UpdateItem.jsx
create mode 100644 frontend/src/modules/AdvancedCrudModule/index.jsx
create mode 100644 frontend/src/modules/EmailModule/EmailDataTableModule/index.jsx
create mode 100644 frontend/src/modules/EmailModule/ReadEmailModule/components/ReadItem.jsx
create mode 100644 frontend/src/modules/EmailModule/ReadEmailModule/index.jsx
create mode 100644 frontend/src/modules/EmailModule/UpdateEmailModule/componenets/EmailForm.jsx
create mode 100644 frontend/src/modules/EmailModule/UpdateEmailModule/index.jsx
create mode 100644 frontend/src/modules/OfferModule/CreateOfferModule/index.jsx
create mode 100644 frontend/src/modules/OfferModule/Forms/OfferForm.jsx
create mode 100644 frontend/src/modules/OfferModule/OfferDataTableModule/index.jsx
create mode 100644 frontend/src/modules/OfferModule/ReadOfferModule/ReadOfferItem.jsx
create mode 100644 frontend/src/modules/OfferModule/ReadOfferModule/index.jsx
create mode 100644 frontend/src/modules/OfferModule/UpdateOfferModule/index.jsx
create mode 100644 frontend/src/modules/OrderModule/CreateOrderModule/index.jsx
create mode 100644 frontend/src/modules/OrderModule/Forms/InvoiceForm.jsx
create mode 100644 frontend/src/modules/OrderModule/OrderDataTableModule/index.jsx
create mode 100644 frontend/src/modules/OrderModule/ReadOrderModule/index.jsx
create mode 100644 frontend/src/modules/OrderModule/RecordPaymentModule/components/Payment.jsx
create mode 100644 frontend/src/modules/OrderModule/RecordPaymentModule/components/RecordPayment.jsx
create mode 100644 frontend/src/modules/OrderModule/RecordPaymentModule/index.jsx
create mode 100644 frontend/src/modules/OrderModule/UpdateInvoiceModule/index.jsx
create mode 100644 frontend/src/pages/AdvancedSettings/index.jsx
create mode 100644 frontend/src/pages/Company/config.js
create mode 100644 frontend/src/pages/Company/index.jsx
create mode 100644 frontend/src/pages/Email/EmailRead.jsx
create mode 100644 frontend/src/pages/Email/EmailUpdate.jsx
create mode 100644 frontend/src/pages/Email/index.jsx
create mode 100644 frontend/src/pages/Employee/index.jsx
create mode 100644 frontend/src/pages/Expense/config.js
create mode 100644 frontend/src/pages/Expense/index.jsx
create mode 100644 frontend/src/pages/ExpenseCategory/config.js
create mode 100644 frontend/src/pages/ExpenseCategory/index.jsx
create mode 100644 frontend/src/pages/Inventory/index.jsx
create mode 100644 frontend/src/pages/Lead/config.js
create mode 100644 frontend/src/pages/Lead/index.jsx
create mode 100644 frontend/src/pages/Offer/OfferCreate.jsx
create mode 100644 frontend/src/pages/Offer/OfferRead.jsx
create mode 100644 frontend/src/pages/Offer/OfferUpdate.jsx
create mode 100644 frontend/src/pages/Offer/index.jsx
create mode 100644 frontend/src/pages/Order/index.jsx
create mode 100644 frontend/src/pages/People/config.js
create mode 100644 frontend/src/pages/People/index.jsx
create mode 100644 frontend/src/pages/Product/config.js
create mode 100644 frontend/src/pages/Product/index.jsx
create mode 100644 frontend/src/pages/ProductCategory/config.js
create mode 100644 frontend/src/pages/ProductCategory/index.jsx
create mode 100644 frontend/src/pages/Register.jsx
create mode 100644 frontend/src/redux/translate/actions.js
create mode 100644 frontend/src/redux/translate/index.js
create mode 100644 frontend/src/redux/translate/reducer.js
create mode 100644 frontend/src/redux/translate/selectors.js
create mode 100644 frontend/src/redux/translate/types.js
diff --git a/backend/.env b/backend/.env
index 360866b0c..ac2730e05 100644
--- a/backend/.env
+++ b/backend/.env
@@ -1,5 +1,5 @@
-#DATABASE = "mongodb://localhost:27017"
-#RESEND_API = "your resend_api"
+DATABASE = "mongodb+srv://192105adityashah:12QX651CYMCrGmT6@cluster0.akacd.mongodb.net/testdel?retryWrites=true&w=majority&appName=Cluster0"
+RESEND_API = "re_ZB3uVo4u_DUGNmBHzp22NQXG8GUhE2jA7"
#OPENAI_API_KEY = "your open_ai api key"
JWT_SECRET= "your_private_jwt_secret_key"
NODE_ENV = "production"
diff --git a/backend/Dockerfile b/backend/Dockerfile
new file mode 100644
index 000000000..69b7179bd
--- /dev/null
+++ b/backend/Dockerfile
@@ -0,0 +1,15 @@
+FROM node:20.9.0-alpine
+
+WORKDIR /usr/src/app
+
+RUN npm install -g npm@10.2.4
+
+COPY package*.json ./
+
+COPY . .
+
+RUN npm install
+
+EXPOSE 8888
+
+CMD ["npm", "run", "dev"]
\ No newline at end of file
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 3635c8039..cb2c024df 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -18,7 +18,7 @@
"dotenv": "16.3.1",
"express": "^4.18.2",
"express-fileupload": "^1.4.3",
- "express-rate-limit": "^7.1.5",
+ "express-rate-limit": "^7.4.1",
"glob": "10.3.10",
"html-pdf": "^3.0.1",
"joi": "^17.11.0",
@@ -32,6 +32,9 @@
"node-cache": "^5.1.2",
"openai": "^4.27.0",
"pug": "^3.0.2",
+ "rate-limit-redis": "^4.2.0",
+ "redis": "^4.7.0",
+ "request-ip": "^3.3.0",
"resend": "^2.0.0",
"shortid": "^2.2.16",
"transliteration": "^2.3.5"
@@ -948,6 +951,59 @@
"node": ">=18.0.0"
}
},
+ "node_modules/@redis/bloom": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
+ "integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/client": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.0.tgz",
+ "integrity": "sha512-aR0uffYI700OEEH4gYnitAnv3vzVGXCFvYfdpu/CJKvk4pHfLPEy/JSZyrpQ+15WhXe1yJRXLtfQ84s4mEXnPg==",
+ "dependencies": {
+ "cluster-key-slot": "1.1.2",
+ "generic-pool": "3.9.0",
+ "yallist": "4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@redis/graph": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
+ "integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/json": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
+ "integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/search": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
+ "integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
+ "node_modules/@redis/time-series": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
+ "integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
+ "peerDependencies": {
+ "@redis/client": "^1.0.0"
+ }
+ },
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz",
@@ -2112,6 +2168,14 @@
"node": ">=0.8"
}
},
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2706,9 +2770,9 @@
}
},
"node_modules/express-rate-limit": {
- "version": "7.1.5",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.1.5.tgz",
- "integrity": "sha512-/iVogxu7ueadrepw1bS0X0kaRC/U0afwiYRSLg68Ts+p4Dc85Q5QKsOnPS/QUjPMHvOJQtBDrZgvkOzf8ejUYw==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.4.1.tgz",
+ "integrity": "sha512-KS3efpnpIDVIXopMc65EMbWbUht7qvTCdtCR2dD/IZmi9MIkopYESwyRqLgv8Pfu589+KqDqOdzJWW7AHoACeg==",
"engines": {
"node": ">= 16"
},
@@ -2958,6 +3022,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/generic-pool": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
+ "integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -4526,6 +4598,17 @@
"node": ">= 0.6"
}
},
+ "node_modules/rate-limit-redis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/rate-limit-redis/-/rate-limit-redis-4.2.0.tgz",
+ "integrity": "sha512-wV450NQyKC24NmPosJb2131RoczLdfIJdKCReNwtVpm5998U8SgKrAZrIHaN/NfQgqOHaan8Uq++B4sa5REwjA==",
+ "engines": {
+ "node": ">= 16"
+ },
+ "peerDependencies": {
+ "express-rate-limit": ">= 6"
+ }
+ },
"node_modules/raw-body": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
@@ -4594,6 +4677,19 @@
"node": ">=8.10.0"
}
},
+ "node_modules/redis": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-4.7.0.tgz",
+ "integrity": "sha512-zvmkHEAdGMn+hMRXuMBtu4Vo5P6rHQjLoHftu+lBqq8ZTA3RCVC/WzD790bkKKiNFp7d5/9PcSD19fJyyRvOdQ==",
+ "dependencies": {
+ "@redis/bloom": "1.2.0",
+ "@redis/client": "1.6.0",
+ "@redis/graph": "1.1.1",
+ "@redis/json": "1.0.7",
+ "@redis/search": "1.2.0",
+ "@redis/time-series": "1.1.0"
+ }
+ },
"node_modules/request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -4626,6 +4722,11 @@
"node": ">= 6"
}
},
+ "node_modules/request-ip": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-3.3.0.tgz",
+ "integrity": "sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA=="
+ },
"node_modules/request-progress": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
diff --git a/backend/package.json b/backend/package.json
index ee2b151ea..0646e49c8 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "idurar-erp-crm",
- "version": "4.1.0",
+ "version": "4.0.0",
"engines": {
"npm": "10.2.4",
"node": "20.9.0"
@@ -23,7 +23,7 @@
"dotenv": "16.3.1",
"express": "^4.18.2",
"express-fileupload": "^1.4.3",
- "express-rate-limit": "^7.1.5",
+ "express-rate-limit": "^7.4.1",
"glob": "10.3.10",
"html-pdf": "^3.0.1",
"joi": "^17.11.0",
@@ -37,6 +37,9 @@
"node-cache": "^5.1.2",
"openai": "^4.27.0",
"pug": "^3.0.2",
+ "rate-limit-redis": "^4.2.0",
+ "redis": "^4.7.0",
+ "request-ip": "^3.3.0",
"resend": "^2.0.0",
"shortid": "^2.2.16",
"transliteration": "^2.3.5"
diff --git a/backend/src/controllers/appControllers/clientController/create.js b/backend/src/controllers/appControllers/clientController/create.js
new file mode 100644
index 000000000..fdb96dab3
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/create.js
@@ -0,0 +1,91 @@
+const mongoose = require('mongoose');
+
+const People = mongoose.model('People');
+const Company = mongoose.model('Company');
+
+const create = async (Model, req, res) => {
+ // Creating a new document in the collection
+
+ if (req.body.type === 'people') {
+ if (!req.body.people) {
+ return res.status(403).json({
+ success: false,
+ message: 'Please select a people',
+ });
+ } else {
+ let client = await Model.findOne({
+ people: req.body.people,
+ removed: false,
+ });
+
+ if (client) {
+ return res.status(403).json({
+ success: false,
+ result: null,
+ message: 'Client Already Exist',
+ });
+ }
+
+ let { firstname, lastname } = await People.findOneAndUpdate(
+ {
+ _id: req.body.people,
+ removed: false,
+ },
+ { isClient: true },
+ {
+ new: true, // return the new result instead of the old one
+ runValidators: true,
+ }
+ ).exec();
+ req.body.name = firstname + ' ' + lastname;
+ req.body.company = undefined;
+ }
+ } else {
+ if (!req.body.company) {
+ return res.status(403).json({
+ success: false,
+ message: 'Please select a company',
+ });
+ } else {
+ let client = await Model.findOne({
+ company: req.body.company,
+ removed: false,
+ });
+
+ if (client) {
+ return res.status(403).json({
+ success: false,
+ result: null,
+ message: 'Client Already Exist',
+ });
+ }
+ let { name } = await Company.findOneAndUpdate(
+ {
+ _id: req.body.company,
+ removed: false,
+ },
+ { isClient: true },
+ {
+ new: true, // return the new result instead of the old one
+ runValidators: true,
+ }
+ ).exec();
+ req.body.name = name;
+ req.body.people = undefined;
+ }
+ }
+
+ req.body.removed = false;
+ const result = await new Model({
+ ...req.body,
+ }).save();
+
+ // Returning successfull response
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'Successfully Created the document in Model ',
+ });
+};
+
+module.exports = create;
diff --git a/backend/src/controllers/appControllers/clientController/index.js b/backend/src/controllers/appControllers/clientController/index.js
index 6411c1951..668727b75 100644
--- a/backend/src/controllers/appControllers/clientController/index.js
+++ b/backend/src/controllers/appControllers/clientController/index.js
@@ -1,13 +1,28 @@
const mongoose = require('mongoose');
const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
-
+const remove = require('./remove');
const summary = require('./summary');
+const create = require('./create');
+const read = require('./read');
+const search = require('./search');
+const update = require('./update');
+
+const listAll = require('./listAll');
+const paginatedList = require('./paginatedList');
+
function modelController() {
const Model = mongoose.model('Client');
const methods = createCRUDController('Client');
+ methods.read = (req, res) => read(Model, req, res);
+ methods.delete = (req, res) => remove(Model, req, res);
+ methods.list = (req, res) => paginatedList(Model, req, res);
methods.summary = (req, res) => summary(Model, req, res);
+ methods.create = (req, res) => create(Model, req, res);
+ methods.update = (req, res) => update(Model, req, res);
+ methods.search = (req, res) => search(Model, req, res);
+ methods.listAll = (req, res) => listAll(Model, req, res);
return methods;
}
diff --git a/backend/src/controllers/appControllers/clientController/listAll.js b/backend/src/controllers/appControllers/clientController/listAll.js
new file mode 100644
index 000000000..82a836d44
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/listAll.js
@@ -0,0 +1,30 @@
+const { migrate } = require('./migrate');
+
+const listAll = async (Model, req, res) => {
+ const sort = parseInt(req.query.sort) || 'desc';
+
+ // Query the database for a list of all results
+ const result = await Model.find({
+ removed: false,
+ })
+ .sort({ created: sort })
+ .populate()
+ .exec();
+
+ const migratedData = result.map((x) => migrate(x));
+ if (result.length > 0) {
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = listAll;
diff --git a/backend/src/controllers/appControllers/clientController/migrate.js b/backend/src/controllers/appControllers/clientController/migrate.js
new file mode 100644
index 000000000..cc6659d9a
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/migrate.js
@@ -0,0 +1,16 @@
+exports.migrate = (result) => {
+ const client = result.type === 'people' ? result.people : result.company;
+ let newData = {};
+ newData._id = result._id;
+ newData.type = result.type;
+ newData.name = result.name;
+ newData.phone = client.phone;
+ newData.email = client.email;
+ newData.website = client.website;
+ newData.country = client.country;
+ newData.address = client.address;
+ newData.people = result.people;
+ newData.company = result.company;
+ newData.notes = result.notes;
+ return newData;
+};
diff --git a/backend/src/controllers/appControllers/clientController/paginatedList.js b/backend/src/controllers/appControllers/clientController/paginatedList.js
new file mode 100644
index 000000000..9e121a66a
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/paginatedList.js
@@ -0,0 +1,67 @@
+const { migrate } = require('./migrate');
+
+const paginatedList = async (Model, req, res) => {
+ const page = req.query.page || 1;
+
+ const limit = parseInt(req.query.items) || 10;
+ const skip = page * limit - limit;
+
+ const { sortBy = 'enabled', sortValue = -1, filter, equal } = req.query;
+
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : [];
+
+ let fields;
+
+ fields = fieldsArray.length === 0 ? {} : { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+
+ // Query the database for a list of all results
+ const resultsPromise = Model.find({
+ removed: false,
+ [filter]: equal,
+ ...fields,
+ })
+ .skip(skip)
+ .limit(limit)
+ .sort({ [sortBy]: sortValue })
+ .populate()
+ .exec();
+
+ // Counting the total documents
+ const countPromise = Model.countDocuments({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ });
+ // Resolving both promises
+ const [result, count] = await Promise.all([resultsPromise, countPromise]);
+ // console.log('๐ ~ file: paginatedList.js:23 ~ paginatedList ~ result:', result);
+
+ // Calculating total pages
+ const pages = Math.ceil(count / limit);
+
+ const pagination = { page, pages, count };
+ if (count > 0) {
+ const migratedData = result.map((x) => migrate(x));
+ // console.log('๐ ~ file: paginatedList.js:23 ~ paginatedList ~ migratedData:', migratedData);
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ pagination,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ pagination,
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = paginatedList;
diff --git a/backend/src/controllers/appControllers/clientController/read.js b/backend/src/controllers/appControllers/clientController/read.js
new file mode 100644
index 000000000..9f6c27db0
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/read.js
@@ -0,0 +1,29 @@
+const { migrate } = require('./migrate');
+
+const read = async (Model, req, res) => {
+ // Find document by id
+ let result = await Model.findOne({
+ _id: req.params.id,
+ removed: false,
+ }).exec();
+ // If no results found, return document not found
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No document found ',
+ });
+ } else {
+ // Return success resposne
+
+ const migratedData = migrate(result);
+
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'we found this document ',
+ });
+ }
+};
+
+module.exports = read;
diff --git a/backend/src/controllers/appControllers/clientController/remove.js b/backend/src/controllers/appControllers/clientController/remove.js
new file mode 100644
index 000000000..64f301384
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/remove.js
@@ -0,0 +1,84 @@
+const mongoose = require('mongoose');
+
+const QuoteModel = mongoose.model('Quote');
+const InvoiceModel = mongoose.model('Invoice');
+const People = mongoose.model('People');
+const Company = mongoose.model('Company');
+
+const remove = async (Model, req, res) => {
+ // cannot delete client it it have one invoice or quotes:
+ // check if client have invoice or quotes:
+ const { id } = req.params;
+
+ // first find if there alt least one quote or invoice exist corresponding to the client
+ const resultQuotes = QuoteModel.findOne({
+ client: id,
+ removed: false,
+ }).exec();
+ const resultInvoice = InvoiceModel.findOne({
+ client: id,
+ removed: false,
+ }).exec();
+
+ const [quotes, invoice] = await Promise.allSettled([resultQuotes, resultInvoice]);
+ if (quotes?.value) {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Cannot delete client if client have any quote or invoice',
+ });
+ }
+ if (invoice?.value) {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Cannot delete client if client have any quote or invoice',
+ });
+ }
+
+ let result = await Model.findOneAndDelete({
+ _id: id,
+ removed: false,
+ }).exec();
+
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No client found by this id: ' + id,
+ });
+ }
+
+ if (result.type === 'people') {
+ await People.findOneAndUpdate(
+ {
+ _id: result.people._id,
+ removed: false,
+ },
+ { isClient: false },
+ {
+ new: true, // return the new result instead of the old one
+ runValidators: true,
+ }
+ ).exec();
+ } else {
+ await Company.findOneAndUpdate(
+ {
+ _id: result.company._id,
+ removed: false,
+ },
+ { isClient: false },
+ {
+ new: true, // return the new result instead of the old one
+ runValidators: true,
+ }
+ ).exec();
+ }
+
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Successfully Deleted the client by id: ' + id,
+ });
+};
+module.exports = remove;
diff --git a/backend/src/controllers/appControllers/clientController/search.js b/backend/src/controllers/appControllers/clientController/search.js
new file mode 100644
index 000000000..343d09586
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/search.js
@@ -0,0 +1,51 @@
+const { migrate } = require('./migrate');
+
+const search = async (Model, req, res) => {
+ // console.log(req.query.fields)
+ // if (req.query.q === undefined || req.query.q.trim() === '') {
+ // return res
+ // .status(202)
+ // .json({
+ // success: false,
+ // result: [],
+ // message: 'No document found by this request',
+ // })
+ // .end();
+ // }
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : ['name'];
+
+ const fields = { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+ // console.log(fields)
+
+ let results = await Model.find({
+ ...fields,
+ })
+ .where('removed', false)
+ .limit(20)
+ .exec();
+
+ const migratedData = results.map((x) => migrate(x));
+
+ if (results.length >= 1) {
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res
+ .status(202)
+ .json({
+ success: false,
+ result: [],
+ message: 'No document found by this request',
+ })
+ .end();
+ }
+};
+
+module.exports = search;
diff --git a/backend/src/controllers/appControllers/clientController/update.js b/backend/src/controllers/appControllers/clientController/update.js
new file mode 100644
index 000000000..3068e8a95
--- /dev/null
+++ b/backend/src/controllers/appControllers/clientController/update.js
@@ -0,0 +1,12 @@
+const mongoose = require('mongoose');
+
+const update = async (Model, req, res) => {
+ // Find document by id and updates with the required fields
+ return res.status(200).json({
+ success: false,
+ result: null,
+ message: 'You cant update client once is created',
+ });
+};
+
+module.exports = update;
diff --git a/backend/src/controllers/appControllers/companyController/index.js b/backend/src/controllers/appControllers/companyController/index.js
new file mode 100644
index 000000000..3b3308320
--- /dev/null
+++ b/backend/src/controllers/appControllers/companyController/index.js
@@ -0,0 +1,24 @@
+const mongoose = require('mongoose');
+const { modelsFiles } = require('@/models/utils');
+const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
+
+const remove = require('./remove');
+const update = require('./update');
+
+function modelController() {
+ const modelName = 'Company';
+
+ if (!modelsFiles.includes(modelName)) {
+ throw new Error(`Model ${modelName} does not exist`);
+ } else {
+ const Model = mongoose.model(modelName);
+ const methods = createCRUDController(modelName);
+
+ methods.delete = (req, res) => remove(Model, req, res);
+ methods.update = (req, res) => update(Model, req, res);
+
+ return methods;
+ }
+}
+
+module.exports = modelController();
diff --git a/backend/src/controllers/appControllers/companyController/remove.js b/backend/src/controllers/appControllers/companyController/remove.js
new file mode 100644
index 000000000..f3257244e
--- /dev/null
+++ b/backend/src/controllers/appControllers/companyController/remove.js
@@ -0,0 +1,57 @@
+const mongoose = require('mongoose');
+
+const Client = mongoose.model('Client');
+const People = mongoose.model('People');
+
+const remove = async (Model, req, res) => {
+ // cannot delete client it it have one invoice or Client:
+ // check if client have invoice or quotes:
+ const { id } = req.params;
+
+ // first find if there alt least one quote or invoice exist corresponding to the client
+ const client = await Client.findOne({
+ company: id,
+ removed: false,
+ }).exec();
+ if (client) {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Cannot delete company if company attached to any people or she is client',
+ });
+ }
+ const people = await People.findOne({
+ company: id,
+ removed: false,
+ }).exec();
+ if (people) {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Cannot delete company if company attached to any people or she is client',
+ });
+ }
+
+ // if no People or quote, delete the client
+ const result = await Model.findOneAndUpdate(
+ { _id: id, removed: false },
+ {
+ $set: {
+ removed: true,
+ },
+ }
+ ).exec();
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No people found by this id: ' + id,
+ });
+ }
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'Successfully Deleted the people by id: ' + id,
+ });
+};
+module.exports = remove;
diff --git a/backend/src/controllers/appControllers/companyController/update.js b/backend/src/controllers/appControllers/companyController/update.js
new file mode 100644
index 000000000..7dc04138d
--- /dev/null
+++ b/backend/src/controllers/appControllers/companyController/update.js
@@ -0,0 +1,44 @@
+const mongoose = require('mongoose');
+const Client = mongoose.model('Client');
+const Lead = mongoose.model('People');
+
+const update = async (Model, req, res) => {
+ // Find document by id and updates with the required fields
+ req.body.removed = false;
+ const result = await Model.findOneAndUpdate({ _id: req.params.id, removed: false }, req.body, {
+ new: true, // return the new result instead of the old one
+ runValidators: true,
+ }).exec();
+
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No document found ',
+ });
+ } else {
+ await Client.findOneAndUpdate(
+ { company: result._id },
+ { name: result.name },
+ {
+ new: true, // return the new result instead of the old one
+ }
+ ).exec();
+
+ await Lead.findOneAndUpdate(
+ { company: result._id },
+ { name: result.name },
+ {
+ new: true, // return the new result instead of the old one
+ }
+ ).exec();
+
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'we update this document ',
+ });
+ }
+};
+
+module.exports = update;
diff --git a/backend/src/controllers/appControllers/invoiceController/remove.js b/backend/src/controllers/appControllers/invoiceController/remove.js
index 94bc7bfa6..f4798289d 100644
--- a/backend/src/controllers/appControllers/invoiceController/remove.js
+++ b/backend/src/controllers/appControllers/invoiceController/remove.js
@@ -1,36 +1,13 @@
const mongoose = require('mongoose');
const Model = mongoose.model('Invoice');
-const ModelPayment = mongoose.model('Payment');
+const ModalPayment = mongoose.model('Payment');
const remove = async (req, res) => {
- const deletedInvoice = await Model.findOneAndUpdate(
- {
- _id: req.params.id,
- removed: false,
- },
- {
- $set: {
- removed: true,
- },
- }
- ).exec();
-
- if (!deletedInvoice) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'Invoice not found',
- });
- }
- const paymentsInvoices = await ModelPayment.updateMany(
- { invoice: deletedInvoice._id },
- { $set: { removed: true } }
- );
return res.status(200).json({
success: true,
- result: deletedInvoice,
- message: 'Invoice deleted successfully',
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
diff --git a/backend/src/controllers/appControllers/invoiceController/update.js b/backend/src/controllers/appControllers/invoiceController/update.js
index 64bcbaa51..8fe7f9b31 100644
--- a/backend/src/controllers/appControllers/invoiceController/update.js
+++ b/backend/src/controllers/appControllers/invoiceController/update.js
@@ -8,75 +8,10 @@ const { calculate } = require('@/helpers');
const schema = require('./schemaValidate');
const update = async (req, res) => {
- let body = req.body;
-
- const { error, value } = schema.validate(body);
- if (error) {
- const { details } = error;
- return res.status(400).json({
- success: false,
- result: null,
- message: details[0]?.message,
- });
- }
-
- const previousInvoice = await Model.findOne({
- _id: req.params.id,
- removed: false,
- });
-
- const { credit } = previousInvoice;
-
- const { items = [], taxRate = 0, discount = 0 } = req.body;
-
- if (items.length === 0) {
- return res.status(400).json({
- success: false,
- result: null,
- message: 'Items cannot be empty',
- });
- }
-
- // default
- let subTotal = 0;
- let taxTotal = 0;
- let total = 0;
-
- //Calculate the items array with subTotal, total, taxTotal
- items.map((item) => {
- let total = calculate.multiply(item['quantity'], item['price']);
- //sub total
- subTotal = calculate.add(subTotal, total);
- //item total
- item['total'] = total;
- });
- taxTotal = calculate.multiply(subTotal, taxRate / 100);
- total = calculate.add(subTotal, taxTotal);
-
- body['subTotal'] = subTotal;
- body['taxTotal'] = taxTotal;
- body['total'] = total;
- body['items'] = items;
- body['pdf'] = 'invoice-' + req.params.id + '.pdf';
- if (body.hasOwnProperty('currency')) {
- delete body.currency;
- }
- // Find document by id and updates with the required fields
-
- let paymentStatus =
- calculate.sub(total, discount) === credit ? 'paid' : credit > 0 ? 'partially' : 'unpaid';
- body['paymentStatus'] = paymentStatus;
-
- const result = await Model.findOneAndUpdate({ _id: req.params.id, removed: false }, body, {
- new: true, // return the new result instead of the old one
- }).exec();
-
- // Returning successfull response
-
return res.status(200).json({
success: true,
- result,
- message: 'we update this document ',
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
diff --git a/backend/src/controllers/appControllers/leadController/create.js b/backend/src/controllers/appControllers/leadController/create.js
new file mode 100644
index 000000000..2b70d7ab0
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/create.js
@@ -0,0 +1,51 @@
+const mongoose = require('mongoose');
+const People = mongoose.model('People');
+const Company = mongoose.model('Company');
+
+const create = async (Model, req, res) => {
+ // Creating a new document in the collection
+
+ if (req.body.type === 'people') {
+ if (!req.body.people) {
+ return res.status(403).json({
+ success: false,
+ message: 'Please select a people',
+ });
+ } else {
+ let { firstname, lastname } = await People.findOne({
+ _id: req.body.people,
+ removed: false,
+ }).exec();
+ req.body.name = firstname + ' ' + lastname;
+ req.body.company = null;
+ }
+ } else {
+ if (!req.body.company) {
+ return res.status(403).json({
+ success: false,
+ message: 'Please select a company',
+ });
+ } else {
+ let { name } = await Company.findOne({
+ _id: req.body.company,
+ removed: false,
+ }).exec();
+ req.body.name = name;
+ req.body.people = null;
+ }
+ }
+
+ req.body.removed = false;
+ const result = await new Model({
+ ...req.body,
+ }).save();
+
+ // Returning successfull response
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'Successfully Created the document in Model ',
+ });
+};
+
+module.exports = create;
diff --git a/backend/src/controllers/appControllers/leadController/index.js b/backend/src/controllers/appControllers/leadController/index.js
new file mode 100644
index 000000000..59f036bc8
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/index.js
@@ -0,0 +1,29 @@
+const mongoose = require('mongoose');
+const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
+const remove = require('./remove');
+const summary = require('./summary');
+
+const create = require('./create');
+const update = require('./update');
+const read = require('./read');
+const search = require('./search');
+
+const listAll = require('./listAll');
+const paginatedList = require('./paginatedList');
+
+function modelController() {
+ const modelName = 'Lead';
+ const Model = mongoose.model(modelName);
+ const methods = createCRUDController(modelName);
+ methods.read = (req, res) => read(Model, req, res);
+ methods.delete = (req, res) => remove(Model, req, res);
+ methods.list = (req, res) => paginatedList(Model, req, res);
+ methods.summary = (req, res) => summary(Model, req, res);
+ methods.create = (req, res) => create(Model, req, res);
+ methods.update = (req, res) => update(Model, req, res);
+ methods.search = (req, res) => search(Model, req, res);
+ methods.listAll = (req, res) => listAll(Model, req, res);
+ return methods;
+}
+
+module.exports = modelController();
diff --git a/backend/src/controllers/appControllers/leadController/listAll.js b/backend/src/controllers/appControllers/leadController/listAll.js
new file mode 100644
index 000000000..82a836d44
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/listAll.js
@@ -0,0 +1,30 @@
+const { migrate } = require('./migrate');
+
+const listAll = async (Model, req, res) => {
+ const sort = parseInt(req.query.sort) || 'desc';
+
+ // Query the database for a list of all results
+ const result = await Model.find({
+ removed: false,
+ })
+ .sort({ created: sort })
+ .populate()
+ .exec();
+
+ const migratedData = result.map((x) => migrate(x));
+ if (result.length > 0) {
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = listAll;
diff --git a/backend/src/controllers/appControllers/leadController/migrate.js b/backend/src/controllers/appControllers/leadController/migrate.js
new file mode 100644
index 000000000..69fb308f6
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/migrate.js
@@ -0,0 +1,18 @@
+exports.migrate = (result) => {
+ let lead = result.type === 'people' ? result.people : result.company;
+ let newData = {};
+ newData._id = result._id;
+ newData.type = result.type;
+ newData.status = result.status;
+ newData.source = result.source;
+ newData.name = result.name;
+ newData.phone = lead.phone;
+ newData.email = lead.email;
+ newData.website = lead.website;
+ newData.country = lead.country;
+ newData.address = lead.address;
+ newData.people = result.people;
+ newData.company = result.company;
+ newData.notes = result.notes;
+ return newData;
+};
diff --git a/backend/src/controllers/appControllers/leadController/paginatedList.js b/backend/src/controllers/appControllers/leadController/paginatedList.js
new file mode 100644
index 000000000..dc39e3001
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/paginatedList.js
@@ -0,0 +1,68 @@
+const { migrate } = require('./migrate');
+
+const paginatedList = async (Model, req, res) => {
+ const page = req.query.page || 1;
+
+ const limit = parseInt(req.query.items) || 10;
+ const skip = page * limit - limit;
+
+ const { sortBy = 'enabled', sortValue = -1, filter, equal } = req.query;
+
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : [];
+
+ let fields;
+
+ fields = fieldsArray.length === 0 ? {} : { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+
+ // Query the database for a list of all results
+ const resultsPromise = Model.find({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ })
+ .skip(skip)
+ .limit(limit)
+ .sort({ [sortBy]: sortValue })
+ .populate()
+ .exec();
+
+ // Counting the total documents
+ const countPromise = Model.countDocuments({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ });
+ // Resolving both promises
+ const [result, count] = await Promise.all([resultsPromise, countPromise]);
+ // console.log('๐ ~ file: paginatedList.js:23 ~ paginatedList ~ result:', result);
+
+ // Calculating total pages
+ const pages = Math.ceil(count / limit);
+
+ const pagination = { page, pages, count };
+ if (count > 0) {
+ const migratedData = result.map((x) => migrate(x));
+ // console.log('๐ ~ file: paginatedList.js:23 ~ paginatedList ~ migratedData:', migratedData);
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ pagination,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ pagination,
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = paginatedList;
diff --git a/backend/src/controllers/appControllers/leadController/read.js b/backend/src/controllers/appControllers/leadController/read.js
new file mode 100644
index 000000000..9f6c27db0
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/read.js
@@ -0,0 +1,29 @@
+const { migrate } = require('./migrate');
+
+const read = async (Model, req, res) => {
+ // Find document by id
+ let result = await Model.findOne({
+ _id: req.params.id,
+ removed: false,
+ }).exec();
+ // If no results found, return document not found
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No document found ',
+ });
+ } else {
+ // Return success resposne
+
+ const migratedData = migrate(result);
+
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'we found this document ',
+ });
+ }
+};
+
+module.exports = read;
diff --git a/backend/src/controllers/appControllers/leadController/remove.js b/backend/src/controllers/appControllers/leadController/remove.js
new file mode 100644
index 000000000..00021092d
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/remove.js
@@ -0,0 +1,10 @@
+const mongoose = require('mongoose');
+
+const remove = async (Model, req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+module.exports = remove;
diff --git a/backend/src/controllers/appControllers/leadController/search.js b/backend/src/controllers/appControllers/leadController/search.js
new file mode 100644
index 000000000..e5ab7f765
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/search.js
@@ -0,0 +1,50 @@
+const { migrate } = require('./migrate');
+
+const search = async (Model, req, res) => {
+ // if (req.query.q === undefined || req.query.q.trim() === '') {
+ // return res
+ // .status(202)
+ // .json({
+ // success: false,
+ // result: [],
+ // message: 'No document found by this request',
+ // })
+ // .end();
+ // }
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : ['name'];
+
+ const fields = { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+ // console.log(fields)
+
+ let results = await Model.find({
+ ...fields,
+ })
+ .where('removed', false)
+ .limit(20)
+ .exec();
+
+ const migratedData = results.map((x) => migrate(x));
+
+ if (results.length >= 1) {
+ return res.status(200).json({
+ success: true,
+ result: migratedData,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res
+ .status(202)
+ .json({
+ success: false,
+ result: [],
+ message: 'No document found by this request',
+ })
+ .end();
+ }
+};
+
+module.exports = search;
diff --git a/backend/src/controllers/appControllers/leadController/summary.js b/backend/src/controllers/appControllers/leadController/summary.js
new file mode 100644
index 000000000..8bc80d95a
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/summary.js
@@ -0,0 +1,97 @@
+const mongoose = require('mongoose');
+const moment = require('moment');
+
+const OfferModel = mongoose.model('Offer');
+
+const summary = async (Model, req, res) => {
+ let defaultType = 'month';
+ const { type } = req.query;
+
+ if (type && ['week', 'month', 'year'].includes(type)) {
+ defaultType = type;
+ } else if (type) {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Invalid type',
+ });
+ }
+
+ const currentDate = moment();
+ let startDate = currentDate.clone().startOf(defaultType);
+ let endDate = currentDate.clone().endOf(defaultType);
+
+ const pipeline = [
+ {
+ $facet: {
+ totalClients: [
+ {
+ $match: {
+ removed: false,
+ enabled: true,
+ },
+ },
+ {
+ $count: 'count',
+ },
+ ],
+ newClients: [
+ {
+ $match: {
+ removed: false,
+ created: { $gte: startDate.toDate(), $lte: endDate.toDate() },
+ enabled: true,
+ },
+ },
+ {
+ $count: 'count',
+ },
+ ],
+ activeClients: [
+ {
+ $lookup: {
+ from: OfferModel.collection.name,
+ localField: '_id', // Match _id from ClientModel
+ foreignField: 'lead', // Match client field in OfferModel
+ as: 'offer',
+ },
+ },
+ {
+ $match: {
+ 'offer.removed': false,
+ },
+ },
+ {
+ $group: {
+ _id: '$_id',
+ },
+ },
+ {
+ $count: 'count',
+ },
+ ],
+ },
+ },
+ ];
+
+ const aggregationResult = await Model.aggregate(pipeline);
+
+ const result = aggregationResult[0];
+ const totalClients = result.totalClients[0] ? result.totalClients[0].count : 0;
+ const totalNewClients = result.newClients[0] ? result.newClients[0].count : 0;
+ const activeClients = result.activeClients[0] ? result.activeClients[0].count : 0;
+
+ const totalActiveClientsPercentage = totalClients > 0 ? (activeClients / totalClients) * 100 : 0;
+ const totalNewClientsPercentage = totalClients > 0 ? (totalNewClients / totalClients) * 100 : 0;
+
+ return res.status(200).json({
+ success: true,
+ result: {
+ new: Math.round(totalNewClientsPercentage),
+ active: Math.round(totalActiveClientsPercentage),
+ },
+ message: 'Successfully get summary of new clients',
+ });
+};
+
+module.exports = summary;
diff --git a/backend/src/controllers/appControllers/leadController/update.js b/backend/src/controllers/appControllers/leadController/update.js
new file mode 100644
index 000000000..002d5023b
--- /dev/null
+++ b/backend/src/controllers/appControllers/leadController/update.js
@@ -0,0 +1,13 @@
+const mongoose = require('mongoose');
+const People = mongoose.model('People');
+const Company = mongoose.model('Company');
+
+const update = async (Model, req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+
+module.exports = update;
diff --git a/backend/src/controllers/appControllers/offerController/create.js b/backend/src/controllers/appControllers/offerController/create.js
new file mode 100644
index 000000000..99ca822de
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/create.js
@@ -0,0 +1,61 @@
+const mongoose = require('mongoose');
+
+const Model = mongoose.model('Offer');
+
+const custom = require('@/controllers/pdfController');
+
+const { calculate } = require('@/helpers');
+const { increaseBySettingKey } = require('@/middlewares/settings');
+
+const create = async (req, res) => {
+ const { items = [], taxRate = 0, discount = 0 } = req.body;
+
+ // default
+ let subTotal = 0;
+ let taxTotal = 0;
+ let total = 0;
+ // let credit = 0;
+
+ //Calculate the items array with subTotal, total, taxTotal
+ items.map((item) => {
+ let total = calculate.multiply(item['quantity'], item['price']);
+ //sub total
+ subTotal = calculate.add(subTotal, total);
+ //item total
+ item['total'] = total;
+ });
+ taxTotal = calculate.multiply(subTotal, taxRate / 100);
+ total = calculate.add(subTotal, taxTotal);
+
+ let body = req.body;
+
+ body['subTotal'] = subTotal;
+ body['taxTotal'] = taxTotal;
+ body['total'] = total;
+ body['items'] = items;
+ body['createdBy'] = req.admin._id;
+
+ // Creating a new document in the collection
+ const result = await new Model(body).save();
+ const fileId = 'offer-' + result._id + '.pdf';
+ const updateResult = await Model.findOneAndUpdate(
+ { _id: result._id },
+ { pdf: fileId },
+ {
+ new: true,
+ }
+ ).exec();
+ // Returning successfull response
+
+ increaseBySettingKey({
+ settingKey: 'last_offer_number',
+ });
+
+ // Returning successfull response
+ return res.status(200).json({
+ success: true,
+ result: updateResult,
+ message: 'Offer created successfully',
+ });
+};
+module.exports = create;
diff --git a/backend/src/controllers/appControllers/offerController/index.js b/backend/src/controllers/appControllers/offerController/index.js
new file mode 100644
index 000000000..a9f7c2dd1
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/index.js
@@ -0,0 +1,18 @@
+const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
+const methods = createCRUDController('Offer');
+
+const create = require('./create');
+const summary = require('./summary');
+const update = require('./update');
+const paginatedList = require('./paginatedList');
+const read = require('./read');
+const sendMail = require('./sendMail');
+
+methods.list = paginatedList;
+methods.read = read;
+methods.mail = sendMail;
+methods.create = create;
+methods.update = update;
+methods.summary = summary;
+
+module.exports = methods;
diff --git a/backend/src/controllers/appControllers/offerController/paginatedList.js b/backend/src/controllers/appControllers/offerController/paginatedList.js
new file mode 100644
index 000000000..3fcae7c5a
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/paginatedList.js
@@ -0,0 +1,68 @@
+const mongoose = require('mongoose');
+
+const Model = mongoose.model('Offer');
+
+const paginatedList = async (req, res) => {
+ const page = req.query.page || 1;
+ const limit = parseInt(req.query.items) || 10;
+ const skip = page * limit - limit;
+
+ // Query the database for a list of all results
+ const { sortBy = 'enabled', sortValue = -1, filter, equal } = req.query;
+
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : [];
+
+ let fields;
+
+ fields = fieldsArray.length === 0 ? {} : { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+
+ // Query the database for a list of all results
+ const resultsPromise = Model.find({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ })
+ .skip(skip)
+ .limit(limit)
+ .sort({ [sortBy]: sortValue })
+ .populate('createdBy', 'name')
+ .exec();
+
+ // Counting the total documents
+ const countPromise = Model.countDocuments({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ });
+
+ // Resolving both promises
+ const [result, count] = await Promise.all([resultsPromise, countPromise]);
+ // Calculating total pages
+ const pages = Math.ceil(count / limit);
+
+ // Getting Pagination Object
+ const pagination = { page, pages, count };
+ if (count > 0) {
+ return res.status(200).json({
+ success: true,
+ result,
+ pagination,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ pagination,
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = paginatedList;
diff --git a/backend/src/controllers/appControllers/offerController/read.js b/backend/src/controllers/appControllers/offerController/read.js
new file mode 100644
index 000000000..c74e7dd8a
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/read.js
@@ -0,0 +1,30 @@
+const mongoose = require('mongoose');
+
+const Model = mongoose.model('Offer');
+
+const read = async (req, res) => {
+ // Find document by id
+ const result = await Model.findOne({
+ _id: req.params.id,
+ removed: false,
+ })
+ .populate('createdBy', 'name')
+ .exec();
+ // If no results found, return document not found
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No document found ',
+ });
+ } else {
+ // Return success resposne
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'we found this document ',
+ });
+ }
+};
+
+module.exports = read;
diff --git a/backend/src/controllers/appControllers/offerController/sendMail.js b/backend/src/controllers/appControllers/offerController/sendMail.js
new file mode 100644
index 000000000..5cdabe784
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/sendMail.js
@@ -0,0 +1,9 @@
+const mail = async (req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+
+module.exports = mail;
diff --git a/backend/src/controllers/appControllers/offerController/summary.js b/backend/src/controllers/appControllers/offerController/summary.js
new file mode 100644
index 000000000..56f63b946
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/summary.js
@@ -0,0 +1,123 @@
+const mongoose = require('mongoose');
+const moment = require('moment');
+
+const Model = mongoose.model('Offer');
+
+const summary = async (req, res) => {
+ let defaultType = 'month';
+
+ const { type } = req.query;
+
+ if (type) {
+ if (['week', 'month', 'year'].includes(type)) {
+ defaultType = type;
+ } else {
+ return res.status(400).json({
+ success: false,
+ result: null,
+ message: 'Invalid type',
+ });
+ }
+ }
+
+ const currentDate = moment();
+ let startDate = currentDate.clone().startOf(defaultType);
+ let endDate = currentDate.clone().endOf(defaultType);
+
+ const statuses = ['draft', 'pending', 'sent', 'expired', 'declined', 'accepted'];
+
+ const response = await Model.aggregate([
+ {
+ $match: {
+ removed: false,
+
+ // date: {
+ // $gte: startDate.toDate(),
+ // $lte: endDate.toDate(),
+ // },
+ },
+ },
+ {
+ $facet: {
+ totalOffer: [
+ {
+ $group: {
+ _id: null,
+ total: {
+ $sum: '$total',
+ },
+ count: {
+ $sum: 1,
+ },
+ },
+ },
+ {
+ $project: {
+ _id: 0,
+ total: '$total',
+ count: '$count',
+ },
+ },
+ ],
+ statusCounts: [
+ {
+ $group: {
+ _id: '$status',
+ count: {
+ $sum: 1,
+ },
+ },
+ },
+ {
+ $project: {
+ _id: 0,
+ status: '$_id',
+ count: '$count',
+ },
+ },
+ ],
+ },
+ },
+ ]);
+ let result = [];
+
+ const totalOffers = response[0].totalOffer ? response[0].totalOffer[0] : 0;
+ const statusResult = response[0].statusCounts || [];
+ // const overdueResult = response[0].overdueCounts || [];
+
+ const statusResultMap = statusResult.map((item) => {
+ return {
+ ...item,
+ percentage: Math.round((item.count / totalOffers.count) * 100),
+ };
+ });
+
+ // const overdueResultMap = overdueResult.map((item) => {
+ // return {
+ // ...item,
+ // status: 'expired',
+ // percentage: Math.round((item.count / totalOffers.count) * 100),
+ // };
+ // });
+
+ statuses.forEach((status) => {
+ const found = [...statusResultMap].find((item) => item.status === status);
+ if (found) {
+ result.push(found);
+ }
+ });
+
+ const finalResult = {
+ total: totalOffers?.total,
+ type,
+ performance: result,
+ };
+
+ return res.status(200).json({
+ success: true,
+ result: finalResult,
+ message: `Successfully found all invoices for the last ${defaultType}`,
+ });
+};
+
+module.exports = summary;
diff --git a/backend/src/controllers/appControllers/offerController/update.js b/backend/src/controllers/appControllers/offerController/update.js
new file mode 100644
index 000000000..5d0265e4a
--- /dev/null
+++ b/backend/src/controllers/appControllers/offerController/update.js
@@ -0,0 +1,10 @@
+const mongoose = require('mongoose');
+
+const update = async (req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+module.exports = update;
diff --git a/backend/src/controllers/appControllers/paymentController/remove.js b/backend/src/controllers/appControllers/paymentController/remove.js
index 93939da85..5d329047e 100644
--- a/backend/src/controllers/appControllers/paymentController/remove.js
+++ b/backend/src/controllers/appControllers/paymentController/remove.js
@@ -1,67 +1,8 @@
-const mongoose = require('mongoose');
-
-const Model = mongoose.model('Payment');
-const Invoice = mongoose.model('Invoice');
-
const remove = async (req, res) => {
- // Find document by id and updates with the required fields
- const previousPayment = await Model.findOne({
- _id: req.params.id,
- removed: false,
- });
-
- if (!previousPayment) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'No document found ',
- });
- }
-
- const { _id: paymentId, amount: previousAmount } = previousPayment;
- const { id: invoiceId, total, discount, credit: previousCredit } = previousPayment.invoice;
-
- // Find the document by id and delete it
- let updates = {
- removed: true,
- };
- // Find the document by id and delete it
- const result = await Model.findOneAndUpdate(
- { _id: req.params.id, removed: false },
- { $set: updates },
- {
- new: true, // return the new result instead of the old one
- }
- ).exec();
- // If no results found, return document not found
-
- let paymentStatus =
- total - discount === previousCredit - previousAmount
- ? 'paid'
- : previousCredit - previousAmount > 0
- ? 'partially'
- : 'unpaid';
-
- const updateInvoice = await Invoice.findOneAndUpdate(
- { _id: invoiceId },
- {
- $pull: {
- payment: paymentId,
- },
- $inc: { credit: -previousAmount },
- $set: {
- paymentStatus: paymentStatus,
- },
- },
- {
- new: true, // return the new result instead of the old one
- }
- ).exec();
-
return res.status(200).json({
success: true,
- result,
- message: 'Successfully Deleted the document ',
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
module.exports = remove;
diff --git a/backend/src/controllers/appControllers/paymentController/update.js b/backend/src/controllers/appControllers/paymentController/update.js
index 0691048eb..ca4f0c3b7 100644
--- a/backend/src/controllers/appControllers/paymentController/update.js
+++ b/backend/src/controllers/appControllers/paymentController/update.js
@@ -1,85 +1,8 @@
-const mongoose = require('mongoose');
-
-const Model = mongoose.model('Payment');
-const Invoice = mongoose.model('Invoice');
-const custom = require('@/controllers/pdfController');
-
-const { calculate } = require('@/helpers');
-
const update = async (req, res) => {
- if (req.body.amount === 0) {
- return res.status(202).json({
- success: false,
- result: null,
- message: `The Minimum Amount couldn't be 0`,
- });
- }
- // Find document by id and updates with the required fields
- const previousPayment = await Model.findOne({
- _id: req.params.id,
- removed: false,
- });
-
- const { amount: previousAmount } = previousPayment;
- const { id: invoiceId, total, discount, credit: previousCredit } = previousPayment.invoice;
-
- const { amount: currentAmount } = req.body;
-
- const changedAmount = calculate.sub(currentAmount, previousAmount);
- const maxAmount = calculate.sub(total, calculate.add(discount, previousCredit));
-
- if (changedAmount > maxAmount) {
- return res.status(202).json({
- success: false,
- result: null,
- message: `The Max Amount you can add is ${maxAmount + previousAmount}`,
- error: `The Max Amount you can add is ${maxAmount + previousAmount}`,
- });
- }
-
- let paymentStatus =
- calculate.sub(total, discount) === calculate.add(previousCredit, changedAmount)
- ? 'paid'
- : calculate.add(previousCredit, changedAmount) > 0
- ? 'partially'
- : 'unpaid';
-
- const updatedDate = new Date();
- const updates = {
- number: req.body.number,
- date: req.body.date,
- amount: req.body.amount,
- paymentMode: req.body.paymentMode,
- ref: req.body.ref,
- description: req.body.description,
- updated: updatedDate,
- };
-
- const result = await Model.findOneAndUpdate(
- { _id: req.params.id, removed: false },
- { $set: updates },
- {
- new: true, // return the new result instead of the old one
- }
- ).exec();
-
- const updateInvoice = await Invoice.findOneAndUpdate(
- { _id: result.invoice._id.toString() },
- {
- $inc: { credit: changedAmount },
- $set: {
- paymentStatus: paymentStatus,
- },
- },
- {
- new: true, // return the new result instead of the old one
- }
- ).exec();
-
return res.status(200).json({
success: true,
- result,
- message: 'Successfully updated the Payment ',
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
diff --git a/backend/src/controllers/appControllers/peopleController/index.js b/backend/src/controllers/appControllers/peopleController/index.js
new file mode 100644
index 000000000..7adf66966
--- /dev/null
+++ b/backend/src/controllers/appControllers/peopleController/index.js
@@ -0,0 +1,21 @@
+const mongoose = require('mongoose');
+
+const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
+const read = require('./read');
+const remove = require('./remove');
+const update = require('./update');
+const paginatedList = require('./paginatedList');
+
+function modelController() {
+ const Model = mongoose.model('People');
+ const methods = createCRUDController('People');
+
+ methods.read = (req, res) => read(Model, req, res);
+ methods.update = (req, res) => update(Model, req, res);
+ methods.delete = (req, res) => remove(Model, req, res);
+ methods.list = (req, res) => paginatedList(Model, req, res);
+
+ return methods;
+}
+
+module.exports = modelController();
diff --git a/backend/src/controllers/appControllers/peopleController/paginatedList.js b/backend/src/controllers/appControllers/peopleController/paginatedList.js
new file mode 100644
index 000000000..43b6fe28c
--- /dev/null
+++ b/backend/src/controllers/appControllers/peopleController/paginatedList.js
@@ -0,0 +1,64 @@
+const paginatedList = async (Model, req, res) => {
+ const page = req.query.page || 1;
+ const limit = parseInt(req.query.items) || 10;
+ const skip = page * limit - limit;
+
+ const { sortBy = 'enabled', sortValue = -1, filter, equal } = req.query;
+
+ const fieldsArray = req.query.fields ? req.query.fields.split(',') : [];
+
+ let fields;
+
+ fields = fieldsArray.length === 0 ? {} : { $or: [] };
+
+ for (const field of fieldsArray) {
+ fields.$or.push({ [field]: { $regex: new RegExp(req.query.q, 'i') } });
+ }
+
+ // Query the database for a list of all results
+ const resultsPromise = Model.find({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ })
+ .skip(skip)
+ .limit(limit)
+ .sort({ [sortBy]: sortValue })
+ .populate('company', 'name')
+ .exec();
+
+ // Counting the total documents
+ const countPromise = Model.countDocuments({
+ removed: false,
+
+ [filter]: equal,
+ ...fields,
+ });
+
+ // Resolving both promises
+ const [result, count] = await Promise.all([resultsPromise, countPromise]);
+
+ // Calculating total pages
+ const pages = Math.ceil(count / limit);
+
+ // Getting Pagination Object
+ const pagination = { page, pages, count };
+ if (count > 0) {
+ return res.status(200).json({
+ success: true,
+ result,
+ pagination,
+ message: 'Successfully found all documents',
+ });
+ } else {
+ return res.status(203).json({
+ success: true,
+ result: [],
+ pagination,
+ message: 'Collection is Empty',
+ });
+ }
+};
+
+module.exports = paginatedList;
diff --git a/backend/src/controllers/appControllers/peopleController/read.js b/backend/src/controllers/appControllers/peopleController/read.js
new file mode 100644
index 000000000..8b0f39786
--- /dev/null
+++ b/backend/src/controllers/appControllers/peopleController/read.js
@@ -0,0 +1,26 @@
+const read = async (Model, req, res) => {
+ // Find document by id
+ const result = await Model.findOne({
+ _id: req.params.id,
+ removed: false,
+ })
+ .populate('company', 'name')
+ .exec();
+ // If no results found, return document not found
+ if (!result) {
+ return res.status(404).json({
+ success: false,
+ result: null,
+ message: 'No document found ',
+ });
+ } else {
+ // Return success resposne
+ return res.status(200).json({
+ success: true,
+ result,
+ message: 'we found this document ',
+ });
+ }
+};
+
+module.exports = read;
diff --git a/backend/src/controllers/appControllers/peopleController/remove.js b/backend/src/controllers/appControllers/peopleController/remove.js
new file mode 100644
index 000000000..7e851a28e
--- /dev/null
+++ b/backend/src/controllers/appControllers/peopleController/remove.js
@@ -0,0 +1,8 @@
+const remove = async (Model, req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+module.exports = remove;
diff --git a/backend/src/controllers/appControllers/peopleController/update.js b/backend/src/controllers/appControllers/peopleController/update.js
new file mode 100644
index 000000000..7a2511b4d
--- /dev/null
+++ b/backend/src/controllers/appControllers/peopleController/update.js
@@ -0,0 +1,13 @@
+const mongoose = require('mongoose');
+const Client = mongoose.model('Client');
+const Lead = mongoose.model('People');
+
+const update = async (Model, req, res) => {
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
+};
+
+module.exports = update;
diff --git a/backend/src/controllers/appControllers/quoteController/update.js b/backend/src/controllers/appControllers/quoteController/update.js
index a4f32696d..a649e634d 100644
--- a/backend/src/controllers/appControllers/quoteController/update.js
+++ b/backend/src/controllers/appControllers/quoteController/update.js
@@ -1,61 +1,8 @@
-const mongoose = require('mongoose');
-
-const Model = mongoose.model('Quote');
-
-const custom = require('@/controllers/pdfController');
-
-const { calculate } = require('@/helpers');
-
const update = async (req, res) => {
- const { items = [], taxRate = 0, discount = 0 } = req.body;
-
- if (items.length === 0) {
- return res.status(400).json({
- success: false,
- result: null,
- message: 'Items cannot be empty',
- });
- }
- // default
- let subTotal = 0;
- let taxTotal = 0;
- let total = 0;
- // let credit = 0;
-
- //Calculate the items array with subTotal, total, taxTotal
- items.map((item) => {
- let total = calculate.multiply(item['quantity'], item['price']);
- //sub total
- subTotal = calculate.add(subTotal, total);
- //item total
- item['total'] = total;
- });
- taxTotal = calculate.multiply(subTotal, taxRate / 100);
- total = calculate.add(subTotal, taxTotal);
-
- let body = req.body;
-
- body['subTotal'] = subTotal;
- body['taxTotal'] = taxTotal;
- body['total'] = total;
- body['items'] = items;
- body['pdf'] = 'quote-' + req.params.id + '.pdf';
-
- if (body.hasOwnProperty('currency')) {
- delete body.currency;
- }
- // Find document by id and updates with the required fields
-
- const result = await Model.findOneAndUpdate({ _id: req.params.id, removed: false }, body, {
- new: true, // return the new result instead of the old one
- }).exec();
-
- // Returning successfull response
-
return res.status(200).json({
success: true,
- result,
- message: 'we update this document ',
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
module.exports = update;
diff --git a/backend/src/controllers/appControllers/taxesController/index.js b/backend/src/controllers/appControllers/taxesController/index.js
index ba31f817a..4f6f167dc 100644
--- a/backend/src/controllers/appControllers/taxesController/index.js
+++ b/backend/src/controllers/appControllers/taxesController/index.js
@@ -38,43 +38,10 @@ methods.delete = async (req, res) => {
};
methods.update = async (req, res) => {
- const { id } = req.params;
- const tax = await Model.findOne({
- _id: req.params.id,
- removed: false,
- }).exec();
- const { isDefault = tax.isDefault, enabled = tax.enabled } = req.body;
-
- // if isDefault:false , we update first - isDefault:true
- // if enabled:false and isDefault:true , we update first - isDefault:true
- if (!isDefault || (!enabled && isDefault)) {
- await Model.findOneAndUpdate({ _id: { $ne: id }, enabled: true }, { isDefault: true });
- }
-
- // if isDefault:true and enabled:true, we update other taxes and make is isDefault:false
- if (isDefault && enabled) {
- await Model.updateMany({ _id: { $ne: id } }, { isDefault: false });
- }
-
- const taxesCount = await Model.countDocuments({});
-
- // if enabled:false and it's only one exist, we can't disable
- if ((!enabled || !isDefault) && taxesCount <= 1) {
- return res.status(422).json({
- success: false,
- result: null,
- message: 'You cannot disable the tax because it is the only existing one',
- });
- }
-
- const result = await Model.findOneAndUpdate({ _id: id }, req.body, {
- new: true,
- });
-
return res.status(200).json({
success: true,
- message: 'Tax updated successfully',
- result,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
});
};
diff --git a/backend/src/controllers/coreControllers/emailController/index.js b/backend/src/controllers/coreControllers/emailController/index.js
new file mode 100644
index 000000000..98072d97c
--- /dev/null
+++ b/backend/src/controllers/coreControllers/emailController/index.js
@@ -0,0 +1,14 @@
+const createCRUDController = require('@/controllers/middlewaresControllers/createCRUDController');
+const crudController = createCRUDController('Email');
+
+const emailMethods = {
+ create:crudController.create,
+ read: crudController.read,
+ update: crudController.update,
+ list: crudController.list,
+ listAll: crudController.listAll,
+ filter: crudController.filter,
+ search: crudController.search,
+};
+
+module.exports = emailMethods;
diff --git a/backend/src/controllers/coreControllers/settingController/updateBySettingKey.js b/backend/src/controllers/coreControllers/settingController/updateBySettingKey.js
index f6e1aebc1..d93a0c317 100644
--- a/backend/src/controllers/coreControllers/settingController/updateBySettingKey.js
+++ b/backend/src/controllers/coreControllers/settingController/updateBySettingKey.js
@@ -1,49 +1,9 @@
-const mongoose = require('mongoose');
-
-const Model = mongoose.model('Setting');
-
const updateBySettingKey = async (req, res) => {
- const settingKey = req.params.settingKey || undefined;
-
- if (!settingKey) {
- return res.status(202).json({
- success: false,
- result: null,
- message: 'No settingKey provided ',
- });
- }
- const { settingValue } = req.body;
-
- if (!settingValue) {
- return res.status(202).json({
- success: false,
- result: null,
- message: 'No settingValue provided ',
- });
- }
- const result = await Model.findOneAndUpdate(
- { settingKey },
- {
- settingValue,
- },
- {
- new: true, // return the new result instead of the old one
- runValidators: true,
- }
- ).exec();
- if (!result) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'No document found by this settingKey: ' + settingKey,
- });
- } else {
- return res.status(200).json({
- success: true,
- result,
- message: 'we update this document by this settingKey: ' + settingKey,
- });
- }
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
};
module.exports = updateBySettingKey;
diff --git a/backend/src/controllers/coreControllers/settingController/updateManySetting.js b/backend/src/controllers/coreControllers/settingController/updateManySetting.js
index cdd7c41f2..39b99af8e 100644
--- a/backend/src/controllers/coreControllers/settingController/updateManySetting.js
+++ b/backend/src/controllers/coreControllers/settingController/updateManySetting.js
@@ -1,58 +1,9 @@
-const mongoose = require('mongoose');
-
-const Model = mongoose.model('Setting');
-
const updateManySetting = async (req, res) => {
- // req/body = [{settingKey:"",settingValue}]
- let settingsHasError = false;
- const updateDataArray = [];
- const { settings } = req.body;
-
- for (const setting of settings) {
- if (!setting.hasOwnProperty('settingKey') || !setting.hasOwnProperty('settingValue')) {
- settingsHasError = true;
- break;
- }
-
- const { settingKey, settingValue } = setting;
-
- updateDataArray.push({
- updateOne: {
- filter: { settingKey: settingKey },
- update: { settingValue: settingValue },
- },
- });
- }
-
- if (updateDataArray.length === 0) {
- return res.status(202).json({
- success: false,
- result: null,
- message: 'No settings provided ',
- });
- }
- if (settingsHasError) {
- return res.status(202).json({
- success: false,
- result: null,
- message: 'Settings provided has Error',
- });
- }
- const result = await Model.bulkWrite(updateDataArray);
-
- if (!result || result.nMatched < 1) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'No settings found by to update',
- });
- } else {
- return res.status(200).json({
- success: true,
- result: [],
- message: 'we update all settings',
- });
- }
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
};
module.exports = updateManySetting;
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js
index 546d56311..577c20e2e 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/authUser.js
@@ -2,7 +2,7 @@ const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const authUser = async (req, res, { user, databasePassword, password, UserPasswordModel }) => {
- const isMatch = await bcrypt.compare(databasePassword.salt + password, databasePassword.password);
+ const isMatch = await bcrypt.compare(password, databasePassword.password);
if (!isMatch)
return res.status(403).json({
@@ -28,29 +28,29 @@ const authUser = async (req, res, { user, databasePassword, password, UserPasswo
}
).exec();
- // .cookie(`token_${user.cloud}`, token, {
- // maxAge: req.body.remember ? 365 * 24 * 60 * 60 * 1000 : null,
- // sameSite: 'None',
- // httpOnly: true,
- // secure: true,
- // domain: req.hostname,
- // path: '/',
- // Partitioned: true,
- // })
- res.status(200).json({
- success: true,
- result: {
- _id: user._id,
- name: user.name,
- surname: user.surname,
- role: user.role,
- email: user.email,
- photo: user.photo,
- token: token,
- maxAge: req.body.remember ? 365 : null,
- },
- message: 'Successfully login user',
- });
+ res
+ .status(200)
+ .cookie('token', token, {
+ maxAge: req.body.remember ? 365 * 24 * 60 * 60 * 1000 : null,
+ sameSite: 'Lax',
+ httpOnly: true,
+ secure: false,
+ domain: req.hostname,
+ path: '/',
+ Partitioned: true,
+ })
+ .json({
+ success: true,
+ result: {
+ _id: user._id,
+ name: user.name,
+ surname: user.surname,
+ role: user.role,
+ email: user.email,
+ photo: user.photo,
+ },
+ message: 'Successfully login user',
+ });
} else {
return res.status(403).json({
success: false,
@@ -60,4 +60,4 @@ const authUser = async (req, res, { user, databasePassword, password, UserPasswo
}
};
-module.exports = authUser;
+module.exports = authUser;
\ No newline at end of file
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/forgetPassword.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/forgetPassword.js
index 176cdd1ce..ec90dfe84 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/forgetPassword.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/forgetPassword.js
@@ -35,6 +35,13 @@ const forgetPassword = async (req, res, { userModel }) => {
const user = await User.findOne({ email: email, removed: false });
const databasePassword = await UserPassword.findOne({ user: user._id, removed: false });
+ if (!user.enabled)
+ return res.status(409).json({
+ success: false,
+ result: null,
+ message: 'Your account is disabled, contact your account adminstrator',
+ });
+
// console.log(user);
if (!user)
return res.status(404).json({
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js
index bf45d7b4a..993d8a9af 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/index.js
@@ -1,6 +1,7 @@
const isValidAuthToken = require('./isValidAuthToken');
const login = require('./login');
const logout = require('./logout');
+const register = require('./register');
const forgetPassword = require('./forgetPassword');
const resetPassword = require('./resetPassword');
@@ -17,6 +18,11 @@ const createAuthMiddleware = (userModel) => {
userModel,
});
+ authMethods.register = (req, res) =>
+ register(req, res, {
+ userModel,
+ });
+
authMethods.forgetPassword = (req, res) =>
forgetPassword(req, res, {
userModel,
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/isValidAuthToken.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/isValidAuthToken.js
index 33a963f5e..ce79f4829 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/isValidAuthToken.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/isValidAuthToken.js
@@ -6,11 +6,7 @@ const isValidAuthToken = async (req, res, next, { userModel, jwtSecret = 'JWT_SE
try {
const UserPassword = mongoose.model(userModel + 'Password');
const User = mongoose.model(userModel);
-
- // const token = req.cookies[`token_${cloud._id}`];
- const authHeader = req.headers['authorization'];
- const token = authHeader && authHeader.split(' ')[1]; // Extract the token
-
+ const token = req.cookies.token;
if (!token)
return res.status(401).json({
success: false,
@@ -43,7 +39,6 @@ const isValidAuthToken = async (req, res, next, { userModel, jwtSecret = 'JWT_SE
});
const { loggedSessions } = userPassword;
-
if (!loggedSessions.includes(token))
return res.status(401).json({
success: false,
@@ -57,13 +52,12 @@ const isValidAuthToken = async (req, res, next, { userModel, jwtSecret = 'JWT_SE
next();
}
} catch (error) {
- return res.status(500).json({
+ return res.status(503).json({
success: false,
result: null,
message: error.message,
error: error,
controller: 'isValidAuthToken',
- jwtExpired: true,
});
}
};
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js
index 7b1eccee8..7b57c615e 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/login.js
@@ -1,7 +1,15 @@
+const bcrypt = require('bcryptjs');
+const jwt = require('jsonwebtoken');
const Joi = require('joi');
const mongoose = require('mongoose');
+const checkAndCorrectURL = require('./checkAndCorrectURL');
+const sendMail = require('./sendMail');
+
+const { loadSettings } = require('@/middlewares/settings');
+const { useAppSettings } = require('@/settings');
+
const authUser = require('./authUser');
const login = async (req, res, { userModel }) => {
@@ -48,12 +56,7 @@ const login = async (req, res, { userModel }) => {
});
// authUser if your has correct password
- authUser(req, res, {
- user,
- databasePassword,
- password,
- UserPasswordModel,
- });
+ authUser(req, res, { user, databasePassword, password, UserPasswordModel });
};
module.exports = login;
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/logout.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/logout.js
index 9eea8aedd..253bf753a 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/logout.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/logout.js
@@ -3,33 +3,29 @@ const mongoose = require('mongoose');
const logout = async (req, res, { userModel }) => {
const UserPassword = mongoose.model(userModel + 'Password');
- // const token = req.cookies[`token_${cloud._id}`];
+ const token = req.cookies.token;
+ await UserPassword.findOneAndUpdate(
+ { user: req.admin._id },
+ { $pull: { loggedSessions: token } },
+ {
+ new: true,
+ }
+ ).exec();
- const authHeader = req.headers['authorization'];
- const token = authHeader && authHeader.split(' ')[1]; // Extract the token
-
- if (token)
- await UserPassword.findOneAndUpdate(
- { user: req.admin._id },
- { $pull: { loggedSessions: token } },
- {
- new: true,
- }
- ).exec();
- else
- await UserPassword.findOneAndUpdate(
- { user: req.admin._id },
- { loggedSessions: [] },
- {
- new: true,
- }
- ).exec();
-
- return res.json({
- success: true,
- result: {},
- message: 'Successfully logout',
- });
+ res
+ .clearCookie('token', {
+ maxAge: null,
+ sameSite: 'none',
+ httpOnly: true,
+ secure: true,
+ domain: req.hostname,
+ Path: '/',
+ })
+ .json({
+ success: true,
+ result: {},
+ message: 'Successfully logout',
+ });
};
module.exports = logout;
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js
new file mode 100644
index 000000000..18e193467
--- /dev/null
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/register.js
@@ -0,0 +1,84 @@
+const bcrypt = require('bcryptjs');
+const jwt = require('jsonwebtoken');
+const Joi = require('joi');
+
+const mongoose = require('mongoose');
+
+const checkAndCorrectURL = require('./checkAndCorrectURL');
+const sendMail = require('./sendMail');
+
+const { loadSettings } = require('@/middlewares/settings');
+const { useAppSettings } = require('@/settings');
+
+const register = async (req, res, { userModel }) => {
+ const UserPasswordModel = mongoose.model(userModel + 'Password');
+ const UserModel = mongoose.model(userModel);
+ const { name, email, password, country } = req.body;
+
+ // validate
+ const objectSchema = Joi.object({
+ email: Joi.string()
+ .email({ tlds: { allow: true } })
+ .required(),
+ name: Joi.string().required(),
+ country: Joi.string().required(),
+ password: Joi.string().required(),
+ });
+
+ const { error, value } = objectSchema.validate({ name, email, password, country });
+ if (error) {
+ return res.status(409).json({
+ success: false,
+ result: null,
+ error: error,
+ message: 'Invalid/Missing credentials.',
+ errorMessage: error.message,
+ });
+ }
+
+ const user = await UserModel.findOne({ email: email, removed: false });
+ if (user)
+ return res.status(409).json({
+ success: false,
+ result: null,
+ message: 'An account with this email already exists.',
+ });
+
+ // authUser if your has correct password
+ const salt = await bcrypt.genSalt(10);
+ console.log(salt)
+ const hashedPassword = await bcrypt.hash(password, salt);
+ const newUser = {
+ name: name,
+ email: email,
+ country: country,
+ enabled: true,
+ };
+
+ const createdUser = await UserModel.create(newUser);
+ const newUserPassword = {
+ removed: false,
+ user: createdUser,
+ password: hashedPassword,
+ salt: salt,
+ emailVerified: false,
+ authType: "email",
+ loggedSessions: []
+ }
+ const databasePassword = await UserPasswordModel.create(newUserPassword);
+ if (!createdUser || !databasePassword) {
+ return res.status(500).json({
+ success: false,
+ result: null,
+ message: 'Error creating your account.',
+ });
+ } else {
+ const success = {
+ success: true
+ }
+ const newUser = {...createdUser, ...success}
+ return res.status(200).json(newUser);
+ }
+};
+
+module.exports = register;
\ No newline at end of file
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/resetPassword.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/resetPassword.js
index d9bb0a811..de8eb1a3a 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/resetPassword.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/resetPassword.js
@@ -13,6 +13,31 @@ const resetPassword = async (req, res, { userModel }) => {
const databasePassword = await UserPassword.findOne({ user: userId, removed: false });
const user = await User.findOne({ _id: userId, removed: false }).exec();
+ if (!user.enabled && user.role === 'owner') {
+ const settings = useAppSettings();
+ const idurar_app_email = settings['idurar_app_email'];
+ const idurar_base_url = settings['idurar_base_url'];
+
+ const url = checkAndCorrectURL(idurar_base_url);
+
+ const link = url + '/verify/' + user._id + '/' + databasePassword.emailToken;
+
+ await sendMail({
+ email,
+ name: user.name,
+ link,
+ idurar_app_email,
+ emailToken: databasePassword.emailToken,
+ });
+
+ return res.status(403).json({
+ success: false,
+ result: null,
+ message:
+ 'your email account is not verified , check your email inbox to activate your account',
+ });
+ }
+
if (!user.enabled)
return res.status(409).json({
success: false,
@@ -85,29 +110,29 @@ const resetPassword = async (req, res, { userModel }) => {
databasePassword.resetToken !== undefined &&
databasePassword.resetToken !== null
)
- // .cookie(`token_${user.cloud}`, token, {
- // maxAge: 24 * 60 * 60 * 1000,
- // sameSite: 'None',
- // httpOnly: true,
- // secure: true,
- // domain: req.hostname,
- // path: '/',
- // Partitioned: true,
- // })
- return res.status(200).json({
- success: true,
- result: {
- _id: user._id,
- name: user.name,
- surname: user.surname,
- role: user.role,
- email: user.email,
- photo: user.photo,
- token: token,
- maxAge: req.body.remember ? 365 : null,
- },
- message: 'Successfully resetPassword user',
- });
+ return res
+ .status(200)
+ .cookie('token', token, {
+ maxAge: 24 * 60 * 60 * 1000,
+ sameSite: 'Lax',
+ httpOnly: true,
+ secure: false,
+ domain: req.hostname,
+ path: '/',
+ Partitioned: true,
+ })
+ .json({
+ success: true,
+ result: {
+ _id: user._id,
+ name: user.name,
+ surname: user.surname,
+ role: user.role,
+ email: user.email,
+ photo: user.photo,
+ },
+ message: 'Successfully resetPassword user',
+ });
};
module.exports = resetPassword;
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendIdurarOffer.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendIdurarOffer.js
new file mode 100644
index 000000000..c2826e4fb
--- /dev/null
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendIdurarOffer.js
@@ -0,0 +1,18 @@
+const { afterRegistrationSuccess } = require('@/emailTemplate/emailVerfication');
+
+const { Resend } = require('resend');
+
+const sendIdurarOffer = async ({ email, name }) => {
+ const resend = new Resend(process.env.RESEND_API);
+
+ const { data } = await resend.emails.send({
+ from: 'hello@idurarapp.com',
+ to: email,
+ subject: 'Customize IDURAR ERP CRM or build your own SaaS',
+ html: afterRegistrationSuccess({ name }),
+ });
+
+ return data;
+};
+
+module.exports = sendIdurarOffer;
diff --git a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendMail.js b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendMail.js
index b16d2e487..c1d85fa0c 100644
--- a/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendMail.js
+++ b/backend/src/controllers/middlewaresControllers/createAuthMiddleware/sendMail.js
@@ -1,4 +1,4 @@
-const { passwordVerfication } = require('@/emailTemplate/emailVerfication');
+const { emailVerfication, passwordVerfication } = require('@/emailTemplate/emailVerfication');
const { Resend } = require('resend');
@@ -17,7 +17,10 @@ const sendMail = async ({
from: idurar_app_email,
to: email,
subject,
- html: passwordVerfication({ name, link }),
+ html:
+ type === 'emailVerfication'
+ ? emailVerfication({ name, link, emailToken })
+ : passwordVerfication({ name, link }),
});
return data;
diff --git a/backend/src/controllers/middlewaresControllers/createCRUDController/remove.js b/backend/src/controllers/middlewaresControllers/createCRUDController/remove.js
index 5072eae18..c39be4395 100644
--- a/backend/src/controllers/middlewaresControllers/createCRUDController/remove.js
+++ b/backend/src/controllers/middlewaresControllers/createCRUDController/remove.js
@@ -1,32 +1,9 @@
const remove = async (Model, req, res) => {
- // Find the document by id and delete it
- let updates = {
- removed: true,
- };
- // Find the document by id and delete it
- const result = await Model.findOneAndUpdate(
- {
- _id: req.params.id,
- },
- { $set: updates },
- {
- new: true, // return the new result instead of the old one
- }
- ).exec();
- // If no results found, return document not found
- if (!result) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'No document found ',
- });
- } else {
- return res.status(200).json({
- success: true,
- result,
- message: 'Successfully Deleted the document ',
- });
- }
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
};
module.exports = remove;
diff --git a/backend/src/controllers/middlewaresControllers/createCRUDController/update.js b/backend/src/controllers/middlewaresControllers/createCRUDController/update.js
index 8438598d6..2e4e0f977 100644
--- a/backend/src/controllers/middlewaresControllers/createCRUDController/update.js
+++ b/backend/src/controllers/middlewaresControllers/createCRUDController/update.js
@@ -1,30 +1,9 @@
const update = async (Model, req, res) => {
- // Find document by id and updates with the required fields
- req.body.removed = false;
- const result = await Model.findOneAndUpdate(
- {
- _id: req.params.id,
- removed: false,
- },
- req.body,
- {
- new: true, // return the new result instead of the old one
- runValidators: true,
- }
- ).exec();
- if (!result) {
- return res.status(404).json({
- success: false,
- result: null,
- message: 'No document found ',
- });
- } else {
- return res.status(200).json({
- success: true,
- result,
- message: 'we update this document ',
- });
- }
+ return res.status(200).json({
+ success: true,
+ result: null,
+ message: 'Please Upgrade to Premium Version to have full features',
+ });
};
module.exports = update;
diff --git a/backend/src/controllers/middlewaresControllers/createUserController/updatePassword.js b/backend/src/controllers/middlewaresControllers/createUserController/updatePassword.js
index f9b6d3fb8..df57cb545 100644
--- a/backend/src/controllers/middlewaresControllers/createUserController/updatePassword.js
+++ b/backend/src/controllers/middlewaresControllers/createUserController/updatePassword.js
@@ -17,14 +17,6 @@ const updatePassword = async (userModel, req, res) => {
// Find document by id and updates with the required fields
- if (userProfile.email === 'admin@demo.com') {
- return res.status(403).json({
- success: false,
- result: null,
- message: "you couldn't update demo password",
- });
- }
-
const salt = uniqueId();
const passwordHash = bcrypt.hashSync(salt + password);
diff --git a/backend/src/controllers/middlewaresControllers/createUserController/updateProfile.js b/backend/src/controllers/middlewaresControllers/createUserController/updateProfile.js
index 8842e71be..9a17247c8 100644
--- a/backend/src/controllers/middlewaresControllers/createUserController/updateProfile.js
+++ b/backend/src/controllers/middlewaresControllers/createUserController/updateProfile.js
@@ -5,15 +5,6 @@ const updateProfile = async (userModel, req, res) => {
const reqUserName = userModel.toLowerCase();
const userProfile = req[reqUserName];
-
- if (userProfile.email === 'admin@demo.com') {
- return res.status(403).json({
- success: false,
- result: null,
- message: "you couldn't update demo informations",
- });
- }
-
let updates = req.body.photo
? {
email: req.body.email,
diff --git a/backend/src/controllers/middlewaresControllers/createUserController/updateProfilePassword.js b/backend/src/controllers/middlewaresControllers/createUserController/updateProfilePassword.js
index f8ce21dd9..c3c0c4130 100644
--- a/backend/src/controllers/middlewaresControllers/createUserController/updateProfilePassword.js
+++ b/backend/src/controllers/middlewaresControllers/createUserController/updateProfilePassword.js
@@ -32,13 +32,6 @@ const updateProfilePassword = async (userModel, req, res) => {
salt: salt,
};
- if (userProfile.email === 'admin@demo.com') {
- return res.status(403).json({
- success: false,
- result: null,
- message: "you couldn't update demo password",
- });
- }
const resultPassword = await UserPassword.findOneAndUpdate(
{ user: userProfile._id, removed: false },
{ $set: UserPasswordData },
diff --git a/backend/src/emailTemplate/emailVerfication.js b/backend/src/emailTemplate/emailVerfication.js
index cae578940..393bbcdc5 100644
--- a/backend/src/emailTemplate/emailVerfication.js
+++ b/backend/src/emailTemplate/emailVerfication.js
@@ -1,3 +1,37 @@
+exports.emailVerfication = ({
+ title = 'Verify your email',
+ name = '',
+ link = '',
+ time = new Date(),
+ emailToken,
+}) => {
+ return `
+
+
+
+
+
${title}
+
+
Idurar erp demo verification
ย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟย โโโโโ๏ปฟ
+
+
+
+
${title}
+
+
Hello ${name},
+
Code :
${emailToken}
+
Thank you for signing up for IDURAR ! Before we can activate your account, we kindly ask you to verify your email address by clicking on the link provided below:
+
${link}
+
Thank you for choosing IDURAR. We look forward to having you as a valued user!
+
+
Best regards,
+
Salah Eddine Lalami
+
Founder @ IDURAR
+
+
+ `;
+};
+
exports.passwordVerfication = ({
title = 'Reset your Password',
name = '',
@@ -20,9 +54,43 @@ exports.passwordVerfication = ({
Hello ${name},
We have received a request to reset the password for your account on IDURAR. To proceed with the password reset, please click on the link provided below:
${link}
-
-
+
+ Best regards,
+ Salah Eddine Lalami
+ Founder @ IDURAR
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index cbb786e61..59f9678dd 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -1,24 +1,24 @@
{
"name": "idurar-erp-crm",
- "version": "4.1.0",
+ "version": "4.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "idurar-erp-crm",
- "version": "4.1.0",
+ "version": "4.0.0",
"dependencies": {
"@ant-design/icons": "^5.3.0",
"@ant-design/pro-layout": "^7.17.19",
"@reduxjs/toolkit": "^2.2.1",
- "@vitejs/plugin-react": "^4.3.1",
+ "@vitejs/plugin-react": "^4.2.1",
"antd": "^5.14.1",
"axios": "^1.6.2",
"cross-env": "7.0.3",
"currency.js": "2.0.4",
"dayjs": "^1.11.10",
"just-compare": "^2.3.0",
- "react": "^18.3.1",
+ "react": "^18.2.0",
"react-dom": "^18.2.0",
"react-quill": "^2.0.0",
"react-redux": "^9.1.0",
@@ -26,7 +26,7 @@
"redux": "^5.0.1",
"reselect": "^5.1.0",
"shortid": "^2.2.16",
- "vite": "^5.4.8"
+ "vite": "^5.1.4"
},
"devDependencies": {
"@types/react": "^18.2.38",
@@ -52,12 +52,12 @@
}
},
"node_modules/@ampproject/remapping": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
- "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
"dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
},
"engines": {
"node": ">=6.0.0"
@@ -193,40 +193,40 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
"dependencies": {
- "@babel/highlight": "^7.24.7",
- "picocolors": "^1.0.0"
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/compat-data": {
- "version": "7.25.4",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz",
- "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==",
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz",
+ "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
- "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.5.tgz",
+ "integrity": "sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g==",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.0",
- "@babel/helper-compilation-targets": "^7.25.2",
- "@babel/helper-module-transforms": "^7.25.2",
- "@babel/helpers": "^7.25.0",
- "@babel/parser": "^7.25.0",
- "@babel/template": "^7.25.0",
- "@babel/traverse": "^7.25.2",
- "@babel/types": "^7.25.2",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.5",
+ "@babel/helper-compilation-targets": "^7.22.15",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.5",
+ "@babel/parser": "^7.23.5",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.5",
+ "@babel/types": "^7.23.5",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -242,13 +242,13 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz",
- "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.5.tgz",
+ "integrity": "sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA==",
"dependencies": {
- "@babel/types": "^7.25.6",
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.25",
+ "@babel/types": "^7.23.5",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
},
"engines": {
@@ -256,13 +256,13 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz",
- "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
+ "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
"dependencies": {
- "@babel/compat-data": "^7.25.2",
- "@babel/helper-validator-option": "^7.24.8",
- "browserslist": "^4.23.1",
+ "@babel/compat-data": "^7.22.9",
+ "@babel/helper-validator-option": "^7.22.15",
+ "browserslist": "^4.21.9",
"lru-cache": "^5.1.1",
"semver": "^6.3.1"
},
@@ -270,27 +270,58 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-module-imports": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz",
- "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-module-transforms": {
- "version": "7.25.2",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz",
- "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==",
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
"dependencies": {
- "@babel/helper-module-imports": "^7.24.7",
- "@babel/helper-simple-access": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "@babel/traverse": "^7.25.2"
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
},
"engines": {
"node": ">=6.9.0"
@@ -300,82 +331,89 @@
}
},
"node_modules/@babel/helper-plugin-utils": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz",
- "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+ "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-simple-access": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz",
- "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dependencies": {
- "@babel/traverse": "^7.24.7",
- "@babel/types": "^7.24.7"
+ "@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz",
- "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==",
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-option": {
- "version": "7.24.8",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz",
- "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
+ "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helpers": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz",
- "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.5.tgz",
+ "integrity": "sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg==",
"dependencies": {
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6"
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.5",
+ "@babel/types": "^7.23.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.0.0"
+ "js-tokens": "^4.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz",
- "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==",
- "dependencies": {
- "@babel/types": "^7.25.6"
- },
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.5.tgz",
+ "integrity": "sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ==",
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -384,11 +422,11 @@
}
},
"node_modules/@babel/plugin-transform-react-jsx-self": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz",
- "integrity": "sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==",
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
+ "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
@@ -398,11 +436,11 @@
}
},
"node_modules/@babel/plugin-transform-react-jsx-source": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz",
- "integrity": "sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ==",
+ "version": "7.23.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
+ "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
"dependencies": {
- "@babel/helper-plugin-utils": "^7.24.7"
+ "@babel/helper-plugin-utils": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
@@ -423,29 +461,32 @@
}
},
"node_modules/@babel/template": {
- "version": "7.25.0",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz",
- "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/parser": "^7.25.0",
- "@babel/types": "^7.25.0"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz",
- "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==",
- "dependencies": {
- "@babel/code-frame": "^7.24.7",
- "@babel/generator": "^7.25.6",
- "@babel/parser": "^7.25.6",
- "@babel/template": "^7.25.0",
- "@babel/types": "^7.25.6",
- "debug": "^4.3.1",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.5.tgz",
+ "integrity": "sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w==",
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.5",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.5",
+ "@babel/types": "^7.23.5",
+ "debug": "^4.1.0",
"globals": "^11.1.0"
},
"engines": {
@@ -453,12 +494,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.25.6",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz",
- "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==",
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.5.tgz",
+ "integrity": "sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w==",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.8",
- "@babel/helper-validator-identifier": "^7.24.7",
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -484,9 +525,9 @@
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
},
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
- "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
"cpu": [
"ppc64"
],
@@ -499,9 +540,9 @@
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
- "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"cpu": [
"arm"
],
@@ -514,9 +555,9 @@
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
- "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"cpu": [
"arm64"
],
@@ -529,9 +570,9 @@
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
- "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"cpu": [
"x64"
],
@@ -544,9 +585,9 @@
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
- "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+ "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"cpu": [
"arm64"
],
@@ -559,9 +600,9 @@
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
- "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"cpu": [
"x64"
],
@@ -574,9 +615,9 @@
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
- "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"cpu": [
"arm64"
],
@@ -589,9 +630,9 @@
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
- "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"cpu": [
"x64"
],
@@ -604,9 +645,9 @@
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
- "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"cpu": [
"arm"
],
@@ -619,9 +660,9 @@
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
- "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"cpu": [
"arm64"
],
@@ -634,9 +675,9 @@
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
- "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"cpu": [
"ia32"
],
@@ -649,9 +690,9 @@
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
- "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"cpu": [
"loong64"
],
@@ -664,9 +705,9 @@
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
- "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"cpu": [
"mips64el"
],
@@ -679,9 +720,9 @@
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
- "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"cpu": [
"ppc64"
],
@@ -694,9 +735,9 @@
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
- "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"cpu": [
"riscv64"
],
@@ -709,9 +750,9 @@
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
- "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"cpu": [
"s390x"
],
@@ -724,9 +765,9 @@
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
- "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
@@ -739,9 +780,9 @@
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
- "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"cpu": [
"x64"
],
@@ -754,9 +795,9 @@
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
- "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"cpu": [
"x64"
],
@@ -769,9 +810,9 @@
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
- "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"cpu": [
"x64"
],
@@ -784,9 +825,9 @@
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
- "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"cpu": [
"arm64"
],
@@ -799,9 +840,9 @@
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
- "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"cpu": [
"ia32"
],
@@ -814,9 +855,9 @@
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
- "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"cpu": [
"x64"
],
@@ -933,43 +974,43 @@
"dev": true
},
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dependencies": {
- "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
- "@jridgewell/trace-mapping": "^0.3.24"
+ "@jridgewell/trace-mapping": "^0.3.9"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
- "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
+ "version": "1.4.15",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.25",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
- "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "version": "0.3.20",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -1154,9 +1195,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.5.tgz",
- "integrity": "sha512-SU5cvamg0Eyu/F+kLeMXS7GoahL+OoizlclVFX3l5Ql6yNlywJJ0OuqTzUx0v+aHhPHEB/56CT06GQrRrGNYww==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+ "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
"cpu": [
"arm"
],
@@ -1166,9 +1207,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.5.tgz",
- "integrity": "sha512-S4pit5BP6E5R5C8S6tgU/drvgjtYW76FBuG6+ibG3tMvlD1h9LHVF9KmlmaUBQ8Obou7hEyS+0w+IR/VtxwNMQ==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+ "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
"cpu": [
"arm64"
],
@@ -1178,9 +1219,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.5.tgz",
- "integrity": "sha512-250ZGg4ipTL0TGvLlfACkIxS9+KLtIbn7BCZjsZj88zSg2Lvu3Xdw6dhAhfe/FjjXPVNCtcSp+WZjVsD3a/Zlw==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+ "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
"cpu": [
"arm64"
],
@@ -1190,9 +1231,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.5.tgz",
- "integrity": "sha512-D8brJEFg5D+QxFcW6jYANu+Rr9SlKtTenmsX5hOSzNYVrK5oLAEMTUgKWYJP+wdKyCdeSwnapLsn+OVRFycuQg==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+ "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
"cpu": [
"x64"
],
@@ -1202,9 +1243,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.5.tgz",
- "integrity": "sha512-PNqXYmdNFyWNg0ma5LdY8wP+eQfdvyaBAojAXgO7/gs0Q/6TQJVXAXe8gwW9URjbS0YAammur0fynYGiWsKlXw==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+ "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
"cpu": [
"arm"
],
@@ -1214,9 +1255,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.5.tgz",
- "integrity": "sha512-kSSCZOKz3HqlrEuwKd9TYv7vxPYD77vHSUvM2y0YaTGnFc8AdI5TTQRrM1yIp3tXCKrSL9A7JLoILjtad5t8pQ==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+ "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
"cpu": [
"arm"
],
@@ -1226,9 +1267,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.5.tgz",
- "integrity": "sha512-oTXQeJHRbOnwRnRffb6bmqmUugz0glXaPyspp4gbQOPVApdpRrY/j7KP3lr7M8kTfQTyrBUzFjj5EuHAhqH4/w==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+ "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
"cpu": [
"arm64"
],
@@ -1238,9 +1279,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.5.tgz",
- "integrity": "sha512-qnOTIIs6tIGFKCHdhYitgC2XQ2X25InIbZFor5wh+mALH84qnFHvc+vmWUpyX97B0hNvwNUL4B+MB8vJvH65Fw==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+ "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
"cpu": [
"arm64"
],
@@ -1250,9 +1291,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.5.tgz",
- "integrity": "sha512-TMYu+DUdNlgBXING13rHSfUc3Ky5nLPbWs4bFnT+R6Vu3OvXkTkixvvBKk8uO4MT5Ab6lC3U7x8S8El2q5o56w==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+ "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
"cpu": [
"ppc64"
],
@@ -1262,9 +1303,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.5.tgz",
- "integrity": "sha512-PTQq1Kz22ZRvuhr3uURH+U/Q/a0pbxJoICGSprNLAoBEkyD3Sh9qP5I0Asn0y0wejXQBbsVMRZRxlbGFD9OK4A==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+ "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
"cpu": [
"riscv64"
],
@@ -1274,9 +1315,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.5.tgz",
- "integrity": "sha512-bR5nCojtpuMss6TDEmf/jnBnzlo+6n1UhgwqUvRoe4VIotC7FG1IKkyJbwsT7JDsF2jxR+NTnuOwiGv0hLyDoQ==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+ "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
"cpu": [
"s390x"
],
@@ -1286,9 +1327,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.5.tgz",
- "integrity": "sha512-N0jPPhHjGShcB9/XXZQWuWBKZQnC1F36Ce3sDqWpujsGjDz/CQtOL9LgTrJ+rJC8MJeesMWrMWVLKKNR/tMOCA==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+ "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
"cpu": [
"x64"
],
@@ -1298,9 +1339,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.5.tgz",
- "integrity": "sha512-uBa2e28ohzNNwjr6Uxm4XyaA1M/8aTgfF2T7UIlElLaeXkgpmIJ2EitVNQxjO9xLLLy60YqAgKn/AqSpCUkE9g==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+ "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
"cpu": [
"x64"
],
@@ -1310,9 +1351,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.5.tgz",
- "integrity": "sha512-RXT8S1HP8AFN/Kr3tg4fuYrNxZ/pZf1HemC5Tsddc6HzgGnJm0+Lh5rAHJkDuW3StI0ynNXukidROMXYl6ew8w==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+ "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
"cpu": [
"arm64"
],
@@ -1322,9 +1363,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.5.tgz",
- "integrity": "sha512-ElTYOh50InL8kzyUD6XsnPit7jYCKrphmddKAe1/Ytt74apOxDq5YEcbsiKs0fR3vff3jEneMM+3I7jbqaMyBg==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+ "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
"cpu": [
"ia32"
],
@@ -1334,9 +1375,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.5.tgz",
- "integrity": "sha512-+lvL/4mQxSV8MukpkKyyvfwhH266COcWlXE/1qxwN08ajovta3459zrjLghYMgDerlzNwLAcFpvU+WWE5y6nAQ==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+ "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
"cpu": [
"x64"
],
@@ -1383,9 +1424,9 @@
}
},
"node_modules/@types/estree": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
- "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
},
"node_modules/@types/prop-types": {
"version": "15.7.10",
@@ -1452,15 +1493,15 @@
"dev": true
},
"node_modules/@vitejs/plugin-react": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz",
- "integrity": "sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg==",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz",
+ "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==",
"dependencies": {
- "@babel/core": "^7.24.5",
- "@babel/plugin-transform-react-jsx-self": "^7.24.5",
- "@babel/plugin-transform-react-jsx-source": "^7.24.1",
+ "@babel/core": "^7.23.5",
+ "@babel/plugin-transform-react-jsx-self": "^7.23.3",
+ "@babel/plugin-transform-react-jsx-source": "^7.23.3",
"@types/babel__core": "^7.20.5",
- "react-refresh": "^0.14.2"
+ "react-refresh": "^0.14.0"
},
"engines": {
"node": "^14.18.0 || >=16.0.0"
@@ -1759,9 +1800,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.24.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
- "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
+ "version": "4.22.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
+ "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
"funding": [
{
"type": "opencollective",
@@ -1777,10 +1818,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001663",
- "electron-to-chromium": "^1.5.28",
- "node-releases": "^2.0.18",
- "update-browserslist-db": "^1.1.0"
+ "caniuse-lite": "^1.0.30001541",
+ "electron-to-chromium": "^1.4.535",
+ "node-releases": "^2.0.13",
+ "update-browserslist-db": "^1.0.13"
},
"bin": {
"browserslist": "cli.js"
@@ -1812,9 +1853,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001664",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001664.tgz",
- "integrity": "sha512-AmE7k4dXiNKQipgn7a2xg558IRqPN3jMQY/rOsbxDhrd0tyChwbITBfiwtnqz8bi2M5mIWbxAYBvk7W7QBUS2g==",
+ "version": "1.0.30001563",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001563.tgz",
+ "integrity": "sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==",
"funding": [
{
"type": "opencollective",
@@ -2048,9 +2089,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.5.29",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.29.tgz",
- "integrity": "sha512-PF8n2AlIhCKXQ+gTpiJi0VhcHDb69kYX4MtCiivctc2QD3XuNZ/XIOlbGzt7WAjjEev0TtaH6Cu3arZExm5DOw=="
+ "version": "1.4.588",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.588.tgz",
+ "integrity": "sha512-soytjxwbgcCu7nh5Pf4S2/4wa6UIu+A3p03U2yVr53qGxi1/VTR3ENI+p50v+UxqqZAfl48j3z55ud7VHIOr9w=="
},
"node_modules/es-abstract": {
"version": "1.22.3",
@@ -2168,9 +2209,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
- "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -2179,35 +2220,35 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.21.5",
- "@esbuild/android-arm": "0.21.5",
- "@esbuild/android-arm64": "0.21.5",
- "@esbuild/android-x64": "0.21.5",
- "@esbuild/darwin-arm64": "0.21.5",
- "@esbuild/darwin-x64": "0.21.5",
- "@esbuild/freebsd-arm64": "0.21.5",
- "@esbuild/freebsd-x64": "0.21.5",
- "@esbuild/linux-arm": "0.21.5",
- "@esbuild/linux-arm64": "0.21.5",
- "@esbuild/linux-ia32": "0.21.5",
- "@esbuild/linux-loong64": "0.21.5",
- "@esbuild/linux-mips64el": "0.21.5",
- "@esbuild/linux-ppc64": "0.21.5",
- "@esbuild/linux-riscv64": "0.21.5",
- "@esbuild/linux-s390x": "0.21.5",
- "@esbuild/linux-x64": "0.21.5",
- "@esbuild/netbsd-x64": "0.21.5",
- "@esbuild/openbsd-x64": "0.21.5",
- "@esbuild/sunos-x64": "0.21.5",
- "@esbuild/win32-arm64": "0.21.5",
- "@esbuild/win32-ia32": "0.21.5",
- "@esbuild/win32-x64": "0.21.5"
+ "@esbuild/aix-ppc64": "0.20.2",
+ "@esbuild/android-arm": "0.20.2",
+ "@esbuild/android-arm64": "0.20.2",
+ "@esbuild/android-x64": "0.20.2",
+ "@esbuild/darwin-arm64": "0.20.2",
+ "@esbuild/darwin-x64": "0.20.2",
+ "@esbuild/freebsd-arm64": "0.20.2",
+ "@esbuild/freebsd-x64": "0.20.2",
+ "@esbuild/linux-arm": "0.20.2",
+ "@esbuild/linux-arm64": "0.20.2",
+ "@esbuild/linux-ia32": "0.20.2",
+ "@esbuild/linux-loong64": "0.20.2",
+ "@esbuild/linux-mips64el": "0.20.2",
+ "@esbuild/linux-ppc64": "0.20.2",
+ "@esbuild/linux-riscv64": "0.20.2",
+ "@esbuild/linux-s390x": "0.20.2",
+ "@esbuild/linux-x64": "0.20.2",
+ "@esbuild/netbsd-x64": "0.20.2",
+ "@esbuild/openbsd-x64": "0.20.2",
+ "@esbuild/sunos-x64": "0.20.2",
+ "@esbuild/win32-arm64": "0.20.2",
+ "@esbuild/win32-ia32": "0.20.2",
+ "@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"engines": {
"node": ">=6"
}
@@ -3505,9 +3546,9 @@
"dev": true
},
"node_modules/node-releases": {
- "version": "2.0.18",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
- "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
+ "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
},
"node_modules/object-assign": {
"version": "4.1.1",
@@ -3745,14 +3786,14 @@
"integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w=="
},
"node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
"node_modules/postcss": {
- "version": "8.4.47",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
- "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+ "version": "8.4.38",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+ "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"funding": [
{
"type": "opencollective",
@@ -3769,8 +3810,8 @@
],
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.1.0",
- "source-map-js": "^1.2.1"
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -4474,9 +4515,9 @@
}
},
"node_modules/react": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -4543,9 +4584,9 @@
}
},
"node_modules/react-refresh": {
- "version": "0.14.2",
- "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
- "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==",
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz",
+ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
"engines": {
"node": ">=0.10.0"
}
@@ -4696,11 +4737,11 @@
}
},
"node_modules/rollup": {
- "version": "4.22.5",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.5.tgz",
- "integrity": "sha512-WoinX7GeQOFMGznEcWA1WrTQCd/tpEbMkc3nuMs9BT0CPjMdSjPMTVClwWd4pgSQwJdP65SK9mTCNvItlr5o7w==",
+ "version": "4.18.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+ "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
"dependencies": {
- "@types/estree": "1.0.6"
+ "@types/estree": "1.0.5"
},
"bin": {
"rollup": "dist/bin/rollup"
@@ -4710,22 +4751,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.22.5",
- "@rollup/rollup-android-arm64": "4.22.5",
- "@rollup/rollup-darwin-arm64": "4.22.5",
- "@rollup/rollup-darwin-x64": "4.22.5",
- "@rollup/rollup-linux-arm-gnueabihf": "4.22.5",
- "@rollup/rollup-linux-arm-musleabihf": "4.22.5",
- "@rollup/rollup-linux-arm64-gnu": "4.22.5",
- "@rollup/rollup-linux-arm64-musl": "4.22.5",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.22.5",
- "@rollup/rollup-linux-riscv64-gnu": "4.22.5",
- "@rollup/rollup-linux-s390x-gnu": "4.22.5",
- "@rollup/rollup-linux-x64-gnu": "4.22.5",
- "@rollup/rollup-linux-x64-musl": "4.22.5",
- "@rollup/rollup-win32-arm64-msvc": "4.22.5",
- "@rollup/rollup-win32-ia32-msvc": "4.22.5",
- "@rollup/rollup-win32-x64-msvc": "4.22.5",
+ "@rollup/rollup-android-arm-eabi": "4.18.0",
+ "@rollup/rollup-android-arm64": "4.18.0",
+ "@rollup/rollup-darwin-arm64": "4.18.0",
+ "@rollup/rollup-darwin-x64": "4.18.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.18.0",
+ "@rollup/rollup-linux-arm64-musl": "4.18.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-gnu": "4.18.0",
+ "@rollup/rollup-linux-x64-musl": "4.18.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.18.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.18.0",
+ "@rollup/rollup-win32-x64-msvc": "4.18.0",
"fsevents": "~2.3.2"
}
},
@@ -4886,9 +4927,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
+ "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"engines": {
"node": ">=0.10.0"
}
@@ -5159,9 +5200,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
- "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
"funding": [
{
"type": "opencollective",
@@ -5177,8 +5218,8 @@
}
],
"dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.0"
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -5205,13 +5246,13 @@
}
},
"node_modules/vite": {
- "version": "5.4.8",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
- "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
+ "version": "5.2.11",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz",
+ "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==",
"dependencies": {
- "esbuild": "^0.21.3",
- "postcss": "^8.4.43",
- "rollup": "^4.20.0"
+ "esbuild": "^0.20.1",
+ "postcss": "^8.4.38",
+ "rollup": "^4.13.0"
},
"bin": {
"vite": "bin/vite.js"
@@ -5230,7 +5271,6 @@
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
- "sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
@@ -5248,9 +5288,6 @@
"sass": {
"optional": true
},
- "sass-embedded": {
- "optional": true
- },
"stylus": {
"optional": true
},
diff --git a/frontend/package.json b/frontend/package.json
index 23e979115..f0a37ad0b 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,23 +1,23 @@
{
"name": "idurar-erp-crm",
- "version": "4.1.0",
+ "version": "4.0.0",
"engines": {
- "node": "20.9.0",
- "npm": "10.2.4"
+ "npm": "10.2.4",
+ "node": "20.9.0"
},
"type": "module",
"dependencies": {
"@ant-design/icons": "^5.3.0",
"@ant-design/pro-layout": "^7.17.19",
"@reduxjs/toolkit": "^2.2.1",
- "@vitejs/plugin-react": "^4.3.1",
+ "@vitejs/plugin-react": "^4.2.1",
"antd": "^5.14.1",
"axios": "^1.6.2",
"cross-env": "7.0.3",
"currency.js": "2.0.4",
"dayjs": "^1.11.10",
"just-compare": "^2.3.0",
- "react": "^18.3.1",
+ "react": "^18.2.0",
"react-dom": "^18.2.0",
"react-quill": "^2.0.0",
"react-redux": "^9.1.0",
@@ -25,7 +25,7 @@
"redux": "^5.0.1",
"reselect": "^5.1.0",
"shortid": "^2.2.16",
- "vite": "^5.4.8"
+ "vite": "^5.1.4"
},
"scripts": {
"dev": "vite",
diff --git a/frontend/src/apps/ErpApp.jsx b/frontend/src/apps/ErpApp.jsx
index ffb97de95..a197aee32 100644
--- a/frontend/src/apps/ErpApp.jsx
+++ b/frontend/src/apps/ErpApp.jsx
@@ -8,12 +8,13 @@ import { Layout } from 'antd';
import { useAppContext } from '@/context/appContext';
import Navigation from '@/apps/Navigation/NavigationContainer';
-
+import ExpensesNav from '@/apps/Navigation/ExpensesNav';
import HeaderContent from '@/apps/Header/HeaderContainer';
import PageLoader from '@/components/PageLoader';
import { settingsAction } from '@/redux/settings/actions';
+import { translateAction } from '@/redux/translate/actions';
import { selectSettings } from '@/redux/settings/selectors';
import AppRouter from '@/router/AppRouter';
@@ -21,13 +22,14 @@ import AppRouter from '@/router/AppRouter';
import useResponsive from '@/hooks/useResponsive';
import storePersist from '@/redux/storePersist';
+import { selectLangDirection } from '@/redux/translate/selectors';
export default function ErpCrmApp() {
const { Content } = Layout;
- // const { state: stateApp, appContextAction } = useAppContext();
- // // const { app } = appContextAction;
- // const { isNavMenuClose, currentApp } = stateApp;
+ const { state: stateApp, appContextAction } = useAppContext();
+ const { app } = appContextAction;
+ const { isNavMenuClose, currentApp } = stateApp;
const { isMobile } = useResponsive();
@@ -37,20 +39,23 @@ export default function ErpCrmApp() {
dispatch(settingsAction.list({ entity: 'setting' }));
}, []);
- // const appSettings = useSelector(selectAppSettings);
+ const appSettings = useSelector(selectAppSettings);
const { isSuccess: settingIsloaded } = useSelector(selectSettings);
- // useEffect(() => {
- // const { loadDefaultLang } = storePersist.get('firstVisit');
- // if (appSettings.idurar_app_language && !loadDefaultLang) {
- // window.localStorage.setItem('firstVisit', JSON.stringify({ loadDefaultLang: true }));
- // }
- // }, [appSettings]);
+ useEffect(() => {
+ const { loadDefaultLang } = storePersist.get('firstVisit');
+ if (appSettings.idurar_app_language && !loadDefaultLang) {
+ dispatch(translateAction.translate(appSettings.idurar_app_language));
+ window.localStorage.setItem('firstVisit', JSON.stringify({ loadDefaultLang: true }));
+ }
+ }, [appSettings]);
+ const langDirection = useSelector(selectLangDirection);
if (settingIsloaded)
return (
-
+
+ {/* {currentApp === 'default' ? : } */}
{isMobile ? (
diff --git a/frontend/src/apps/Header/HeaderContainer.jsx b/frontend/src/apps/Header/HeaderContainer.jsx
index d60568e6d..305672c72 100644
--- a/frontend/src/apps/Header/HeaderContainer.jsx
+++ b/frontend/src/apps/Header/HeaderContainer.jsx
@@ -1,6 +1,6 @@
import { useSelector } from 'react-redux';
import { Link, useNavigate } from 'react-router-dom';
-import { Avatar, Dropdown, Layout, Badge, Button } from 'antd';
+import { Avatar, Dropdown, Layout } from 'antd';
// import Notifications from '@/components/Notification';
@@ -14,6 +14,8 @@ import useLanguage from '@/locale/useLanguage';
import UpgradeButton from './UpgradeButton';
+import { selectLangDirection } from '@/redux/translate/selectors';
+
export default function HeaderContent() {
const currentAdmin = useSelector(selectCurrentAdmin);
const { Header } = Layout;
@@ -84,13 +86,14 @@ export default function HeaderContent() {
},
];
+ const langDirection = useSelector(selectLangDirection);
return (