From d811f802da7c4e6dda1e3b12a312d7437f14c0d9 Mon Sep 17 00:00:00 2001 From: Tibebe Solomon <87706650+Tibex88@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:30:36 +0300 Subject: [PATCH 01/59] added logActivity to mw --- server/app.js | 2 +- server/controller/exam/createExam.js | 4 + server/controller/exam/updateExam.js | 4 +- server/controller/handlerFactory.js | 86 ++++--------------- server/controller/log/getLogs.js | 11 +++ server/controller/log/index.js | 5 ++ .../notification/getNotification.js | 1 - .../organization/activateExaminer.js | 4 + .../organization/createOrganization.js | 2 + .../organization/deactivateExaminer.js | 3 + .../organization/joinOrganization.js | 2 + .../organization/updateOrganizationLogo.js | 2 + server/controller/profile/fileUpload.js | 2 +- server/models/log.model.js | 34 ++++++++ server/models/user.model.js | 18 ++-- server/routes/logRoutes.js | 9 ++ server/routes/routes.js | 2 + server/utils/logActivity.js | 21 +++++ 18 files changed, 128 insertions(+), 84 deletions(-) create mode 100644 server/controller/log/getLogs.js create mode 100644 server/controller/log/index.js create mode 100644 server/models/log.model.js create mode 100644 server/routes/logRoutes.js create mode 100644 server/utils/logActivity.js diff --git a/server/app.js b/server/app.js index 3f9e76e..d3b6157 100644 --- a/server/app.js +++ b/server/app.js @@ -2,7 +2,7 @@ const express = require("express"); const app = express(); const cors = require("cors"); const morgan = require("morgan"); -const APIError = require("./utils/APIError"); +const APIError = require("./utils/apiError"); const globalErrorHandler = require("./controller/errorController"); const helmet = require("helmet"); const rateLimit = require("express-rate-limit"); diff --git a/server/controller/exam/createExam.js b/server/controller/exam/createExam.js index b15f244..009fbc3 100644 --- a/server/controller/exam/createExam.js +++ b/server/controller/exam/createExam.js @@ -4,6 +4,8 @@ const APIError = require("../../utils/apiError"); const catchAsync = require("../../utils/catchAsync"); const { fileUpload } = require("../profile/fileUpload"); const generateRandomKey = require("../../utils/generateRandomKey"); +const { logActivity } = require("../../utils/logActivity"); + exports.createExam = catchAsync(async (req, res, next) => { // form data will be send in req, holding in the req.file the material that is a PDF file @@ -80,6 +82,8 @@ exports.createExam = catchAsync(async (req, res, next) => { await exam.save(); + await logActivity(req,0,{name:exam?.modelName,id:exam.id} ) + res.status(201).json({ status: "success", data: { diff --git a/server/controller/exam/updateExam.js b/server/controller/exam/updateExam.js index a203e2f..00aab3f 100644 --- a/server/controller/exam/updateExam.js +++ b/server/controller/exam/updateExam.js @@ -2,7 +2,7 @@ const { StatusCodes } = require("http-status-codes"); const Exam = require("../../models/exam.model"); const catchAsync = require("../../utils/catchAsync"); const factory = require("./../handlerFactory"); -const APIError = require("../../utils/APIError"); +const APIError = require("../../utils/apiError"); const { fileUpload } = require("../profile/fileUpload"); const Question = require("../../models/question.model"); @@ -64,6 +64,8 @@ exports.updateExamResource = catchAsync(async (req, res, next) => { await exam.save(); + await logActivity(req,1,{name:exam?.modelName,id:exam.id} ) + res.status(StatusCodes.OK).json({ status: "success", data: { diff --git a/server/controller/handlerFactory.js b/server/controller/handlerFactory.js index cbacab1..bc7c8b2 100644 --- a/server/controller/handlerFactory.js +++ b/server/controller/handlerFactory.js @@ -1,13 +1,11 @@ const mongoose = require("mongoose"); -// const Grid = require("gridfs-stream"); const APIError = require("../utils/apiError"); const catchAsync = require("../utils/catchAsync"); -// const transaction = require("../utils/transaction"); +const {logActivity} = require("../utils/logActivity"); const APIFeatures = require("../utils/apiFeatures"); const dbConn = require("../config/db_Connection"); -const OrganizationExaminer = require("../models/organization.examiner.model"); +// const OrganizationExaminer = require("../models/organization.examiner.model"); const { StatusCodes } = require("http-status-codes"); -// const dbAuth = require("../config/db_Authentication"); require("events").EventEmitter.prototype._maxListeners = 70; require("events").defaultMaxListeners = 70; @@ -36,12 +34,12 @@ exports.getOne = (Model) => exports.getAll = (Model, options = "", obj = {}) => catchAsync(async (req, res, next) => { // currentTime, pathname, method - // const {currentTime,_parsedOriginalUrl} = req + // const {currentTime,_parsedOriginalUrl} = req // console.log(currentTime) // console.log(_parsedOriginalUrl.pathname) let opt = {}; - if (options === "addUser") opt = { user: req.user.id }; + if (options === "addUser") opt = { user: req.user.id }; if (options === "addOrganization") opt = { organization: req.params.id }; if (options === "addExaminerStatus") opt = { user: req.user.id, status: "activated" }; @@ -106,6 +104,9 @@ exports.updateOne = (Model) => new APIError(`No document found with id = ${req.params.id}`, 404) ); } + + await logActivity(req,1,{name:Model?.modelName,id:req.params.id}) + res.status(200).json({ status: "success", data: { @@ -129,6 +130,7 @@ exports.deleteOne = (Model) => console.log(model) await model.save(); + await logActivity(req,5,{name:Model?.modelName,id:req.params.id} ) res.status(StatusCodes.OK).json({ status: "success", data: null, @@ -162,6 +164,9 @@ exports.createOne = (Model) => new APIError(`An error occured while creating the document`, 404) ); } + + await logActivity(req,0,{name:Model?.modelName,id:doc.id}) + res.status(201).json({ status: "success", data: { @@ -181,6 +186,7 @@ exports.createMany = (Model, returnOnlyId = false) => if (returnOnlyId) { let id = doc.map((item) => item._id); + // await logActivity(req,0,{name:Model?.modelName,id:req.params.id} ) res.status(201).json({ status: "success", data: { @@ -188,6 +194,9 @@ exports.createMany = (Model, returnOnlyId = false) => }, }); } else { + + // await logActivity(req,0,{name:Model?.modelName,id:req.params.id} ) + res.status(201).json({ status: "success", data: { @@ -196,68 +205,3 @@ exports.createMany = (Model, returnOnlyId = false) => }); } }); - -// exports.getOneMedia = (collectionName) => -// catchAsync(async (req, res, next) => { -// console.log(req.params.filename); -// if (collectionName == "userProfile") gridfs = gridfsProfile; -// else if (collectionName == "media") gridfs = gridfsMedia; - -// const result = await gridfs.find({ -// filename: req.params.filename, -// }); -// var filename = ""; -// await result.forEach((doc) => { -// filename = doc.filename; -// return; -// }); -// const readstream = await gridfs.openDownloadStreamByName(filename); - -// readstream -// .on("data", async (chunk) => { -// string = await chunk.toString("base64"); - -// return res.status(200).json({ -// status: "success", -// data: string, -// }); -// }) -// .on("end", function () { -// console.log("end"); -// }) -// .on("error", (err) => { -// console.log(err, "the error"); -// }); -// }); - -// exports.updateOneMedia = (collectionName) => -// catchAsync(async (req, res, next) => { -// gfs.collection(collectionName); -// // gfs.remove({_id:}) -// }); - -// exports.deleteOneMedia = (collectionName) => -// catchAsync(async (req, res, next) => { -// if (collectionName == "userProfile") gridfs = gridfsProfile; -// else if (collectionName == "media") gridfs = gridfsMedia; - -// await gridfs.delete(new mongoose.Types.ObjectId(req.params.id)); -// res.status(204).json({ -// status: "success", -// }); -// }); - -// exports.deleteManyMedia = (collectionName) => -// catchAsync(async (req, res, next) => { -// if (collectionName == "userProfile") gridfs = gridfsProfile; -// else if (collectionName == "media") gridfs = gridfsMedia; - -// // gfs.collection(collectionName + '.chunks'); -// console.log(req.body.delete); -// // gridfs.delete(`ObjectId("${req.body.delete[0]}")`) -// await gridfs.delete(new mongoose.Types.ObjectId(req.body.delete[0])); - -// res.status(200).json({ -// status: "success", -// }); -// }); diff --git a/server/controller/log/getLogs.js b/server/controller/log/getLogs.js new file mode 100644 index 0000000..65c7bf4 --- /dev/null +++ b/server/controller/log/getLogs.js @@ -0,0 +1,11 @@ +const Log = require("../../models/log.model"); +const factory = require("../handlerFactory"); + +// const { TokenModel } = require("../../models/Token.model"); +// const { UserModel } = require("../../models/User.model"); +// const { isTokenValid } = require("../utils"); + +const getLogs = factory.getAll(Log); + +module.exports = getLogs; + diff --git a/server/controller/log/index.js b/server/controller/log/index.js new file mode 100644 index 0000000..e43f482 --- /dev/null +++ b/server/controller/log/index.js @@ -0,0 +1,5 @@ +const getLogs = require("./getLogs"); + +module.exports = { + getLogs +} \ No newline at end of file diff --git a/server/controller/notification/getNotification.js b/server/controller/notification/getNotification.js index f7178df..5a4c314 100644 --- a/server/controller/notification/getNotification.js +++ b/server/controller/notification/getNotification.js @@ -1,6 +1,5 @@ const factory = require("../handlerFactory"); const Notification = require("../../models/notification.model"); -const catchAsync = require("../../utils/catchAsync"); const getNotification = factory.getAll(Notification, "addUser"); diff --git a/server/controller/organization/activateExaminer.js b/server/controller/organization/activateExaminer.js index 5b078a1..9e93547 100644 --- a/server/controller/organization/activateExaminer.js +++ b/server/controller/organization/activateExaminer.js @@ -4,6 +4,7 @@ const APIError = require("../../utils/apiError"); const catchAsync = require("../../utils/catchAsync"); const OrganizationExaminer = require("../../models/organization.examiner.model"); const Notification = require("../../models/notification.model"); +const { logActivity } = require("../../utils/logActivity"); exports.activateExaminer = catchAsync(async (req, res, next) => { const { userId } = req.body; @@ -49,6 +50,9 @@ exports.activateExaminer = catchAsync(async (req, res, next) => { message: `Your account as an Examiner has been Activated. In the Organization ${organization.name}`, }); + await logActivity(req,6,{name:organizationExaminer?.modelName,id:user.id} ) + + res.status(StatusCodes.OK).json({ status: "success", message: "You have successfully approved the join request.", diff --git a/server/controller/organization/createOrganization.js b/server/controller/organization/createOrganization.js index 3e12ade..03b7b86 100644 --- a/server/controller/organization/createOrganization.js +++ b/server/controller/organization/createOrganization.js @@ -6,6 +6,7 @@ const factory = require("../handlerFactory"); const APIError = require("../../utils/apiError"); const { fileUpload } = require("../profile/fileUpload"); const OrganizationExaminer = require("../../models/organization.examiner.model"); +const { logActivity } = require("../../utils/logActivity"); exports.createOrganization = catchAsync(async (req, res, next) => { if (!req.files) { @@ -51,6 +52,7 @@ exports.createOrganization = catchAsync(async (req, res, next) => { status: "activated", }); + await logActivity(req,0,{name:Organization?.modelName,id:newOrganization.id} ) res.status(StatusCodes.CREATED).json({ sucess: true, diff --git a/server/controller/organization/deactivateExaminer.js b/server/controller/organization/deactivateExaminer.js index 057e48f..62460c9 100644 --- a/server/controller/organization/deactivateExaminer.js +++ b/server/controller/organization/deactivateExaminer.js @@ -3,6 +3,7 @@ const Organization = require("../../models/organization.model"); const catchAsync = require("../../utils/catchAsync"); const OrganizationExaminer = require("../../models/organization.examiner.model"); const APIError = require("../../utils/apiError"); +const { logActivity } = require("../../utils/logActivity"); exports.deactivateExaminer = catchAsync(async (req, res, next) => { const { userId } = req.body; @@ -42,6 +43,8 @@ exports.deactivateExaminer = catchAsync(async (req, res, next) => { // save the organization await organizationExaminer.save(); + await logActivity(req,4,{name:organizationExaminer?.modelName,id:userId} ) + res.status(StatusCodes.OK).json({ status: "success", message: "You have successfully deactivated the examinee.", diff --git a/server/controller/organization/joinOrganization.js b/server/controller/organization/joinOrganization.js index 57f0009..d892b24 100644 --- a/server/controller/organization/joinOrganization.js +++ b/server/controller/organization/joinOrganization.js @@ -51,6 +51,8 @@ exports.joinOrganization = catchAsync(async (req, res, next) => { message: `User with id ${userId} has requested to join the organization `, }); + await logActivity(req,7,{name:organization?.modelName,id:organization.id} ) + res.status(StatusCodes.OK).json({ status: "success", message: diff --git a/server/controller/organization/updateOrganizationLogo.js b/server/controller/organization/updateOrganizationLogo.js index 52bbc1e..21c3309 100644 --- a/server/controller/organization/updateOrganizationLogo.js +++ b/server/controller/organization/updateOrganizationLogo.js @@ -38,6 +38,8 @@ exports.updateOrganizationLogo = catchAsync(async (req, res, next) => { organization.logo = logo; await organization.save(); + await logActivity(req,1,{name:organization?.modelName,id:organization.id} ) + res.status(StatusCodes.CREATED).json({ status: "success", data: null, diff --git a/server/controller/profile/fileUpload.js b/server/controller/profile/fileUpload.js index 11bf45b..d8e4446 100644 --- a/server/controller/profile/fileUpload.js +++ b/server/controller/profile/fileUpload.js @@ -3,7 +3,7 @@ const catchAsync = require("./../../utils/catchAsync"); const fs = require("fs"); const { StatusCodes } = require("http-status-codes"); -const APIError = require("../../utils/APIError"); +const APIError = require("../../utils/apiError"); const { CLIENT_RENEG_LIMIT } = require("tls"); const fileUpload = diff --git a/server/models/log.model.js b/server/models/log.model.js new file mode 100644 index 0000000..c93c6f7 --- /dev/null +++ b/server/models/log.model.js @@ -0,0 +1,34 @@ +const mongoose = require("mongoose"); + +const logSchema = new mongoose.Schema({ + user: { + type: mongoose.Schema.Types.ObjectId, + ref: "User", + }, + ipAddress: { + type: String, + required: true + }, + action: { + type: String, + required: true, + default:'unknown' + }, + entity:{ + name:{ + type:String, + default:'none' + }, + id:{ + type:mongoose.Schema.Types.ObjectId + } + } + }, + { + timestamps: true, + } + ); + +const LogModel = mongoose.model("Logs", logSchema); + +module.exports = LogModel; \ No newline at end of file diff --git a/server/models/user.model.js b/server/models/user.model.js index e14ddb7..4673cf5 100644 --- a/server/models/user.model.js +++ b/server/models/user.model.js @@ -108,15 +108,15 @@ const user = new mongoose.Schema( type: Boolean, default: true, }, - role: { - type: String, - required: false, - default: "user", - enum: { - values: ["manager", "receptionist", "user"], - message: "role can be either reception, manager or user", - }, - }, + // role: { + // type: String, + // required: false, + // default: "user", + // enum: { + // values: ["manager", "receptionist", "user"], + // message: "role can be either reception, manager or user", + // }, + // }, // notificationCount: { // type: Number, // default: 0, diff --git a/server/routes/logRoutes.js b/server/routes/logRoutes.js new file mode 100644 index 0000000..083b5cf --- /dev/null +++ b/server/routes/logRoutes.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = express.Router(); +const {getLogs} = require('../controller/log') + +router + .route("/") + .get(getLogs); + +module.exports = router; \ No newline at end of file diff --git a/server/routes/routes.js b/server/routes/routes.js index 53bf599..b0766fd 100644 --- a/server/routes/routes.js +++ b/server/routes/routes.js @@ -7,6 +7,7 @@ const questionRouter = require("./questionRoutes"); const organizationRouter = require("./organizationRoutes"); const notificationRouter = require("./notificationRoutes"); const userAnswerRouter = require("./userAnswerRoutes"); +const logRouter = require("./logRoutes"); router.use("/users", userRouter); router.use("/exams", examRouter); @@ -14,5 +15,6 @@ router.use("/questions", questionRouter); router.use("/organizations", organizationRouter); router.use("/notifications", notificationRouter); router.use("/useranswers", userAnswerRouter); +router.use("/log", logRouter); module.exports = router; diff --git a/server/utils/logActivity.js b/server/utils/logActivity.js new file mode 100644 index 0000000..d8be750 --- /dev/null +++ b/server/utils/logActivity.js @@ -0,0 +1,21 @@ +const Log = require("../models/log.model"); +const actionTypes = ["created","edited","archived","loggedIn","deactivated", "delete","activated","joined"] +// const entities = ["an organization","an exam","user"] + + +const logActivity = async (req,actionIndex, {name,id}) => { + + await Log.create({ + user: req.user.id? req.user._id : 'Unknown', + ipAddress: req.ip? req.ip : 'Unknown', + action:`${actionTypes[actionIndex]}`, + entity:{ + name, + id + } + }); + }; + +module.exports = { + logActivity, +}; \ No newline at end of file From a182e50ee2e9e0bc66f4e30722b0ac97440e68d3 Mon Sep 17 00:00:00 2001 From: Tibebe Solomon <87706650+Tibex88@users.noreply.github.com> Date: Wed, 5 Jun 2024 15:43:34 +0300 Subject: [PATCH 02/59] added logging and debugged --- server/controller/exam/createExam.js | 2 +- server/controller/exam/updateExam.js | 2 +- server/controller/organization/activateExaminer.js | 2 +- server/controller/organization/createOrganization.js | 2 +- server/controller/organization/deactivateExaminer.js | 2 +- server/controller/organization/joinOrganization.js | 2 +- server/controller/organization/updateOrganizationLogo.js | 2 +- server/models/log.model.js | 2 +- server/utils/logActivity.js | 5 +++-- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/server/controller/exam/createExam.js b/server/controller/exam/createExam.js index 009fbc3..6c93712 100644 --- a/server/controller/exam/createExam.js +++ b/server/controller/exam/createExam.js @@ -82,7 +82,7 @@ exports.createExam = catchAsync(async (req, res, next) => { await exam.save(); - await logActivity(req,0,{name:exam?.modelName,id:exam.id} ) + await logActivity(req,0,{name:'exam',id:exam.id} ) res.status(201).json({ status: "success", diff --git a/server/controller/exam/updateExam.js b/server/controller/exam/updateExam.js index 00aab3f..e84c8c0 100644 --- a/server/controller/exam/updateExam.js +++ b/server/controller/exam/updateExam.js @@ -64,7 +64,7 @@ exports.updateExamResource = catchAsync(async (req, res, next) => { await exam.save(); - await logActivity(req,1,{name:exam?.modelName,id:exam.id} ) + await logActivity(req,1,{name:'exam',id:exam.id} ) res.status(StatusCodes.OK).json({ status: "success", diff --git a/server/controller/organization/activateExaminer.js b/server/controller/organization/activateExaminer.js index 9e93547..b7ff088 100644 --- a/server/controller/organization/activateExaminer.js +++ b/server/controller/organization/activateExaminer.js @@ -50,7 +50,7 @@ exports.activateExaminer = catchAsync(async (req, res, next) => { message: `Your account as an Examiner has been Activated. In the Organization ${organization.name}`, }); - await logActivity(req,6,{name:organizationExaminer?.modelName,id:user.id} ) + await logActivity(req,6,{name:'Organization Examiner',id:user.id} ) res.status(StatusCodes.OK).json({ diff --git a/server/controller/organization/createOrganization.js b/server/controller/organization/createOrganization.js index 03b7b86..0fdd89d 100644 --- a/server/controller/organization/createOrganization.js +++ b/server/controller/organization/createOrganization.js @@ -52,7 +52,7 @@ exports.createOrganization = catchAsync(async (req, res, next) => { status: "activated", }); - await logActivity(req,0,{name:Organization?.modelName,id:newOrganization.id} ) + await logActivity(req,0,{name:'Organization',id:newOrganization.id} ) res.status(StatusCodes.CREATED).json({ sucess: true, diff --git a/server/controller/organization/deactivateExaminer.js b/server/controller/organization/deactivateExaminer.js index 62460c9..51c0231 100644 --- a/server/controller/organization/deactivateExaminer.js +++ b/server/controller/organization/deactivateExaminer.js @@ -43,7 +43,7 @@ exports.deactivateExaminer = catchAsync(async (req, res, next) => { // save the organization await organizationExaminer.save(); - await logActivity(req,4,{name:organizationExaminer?.modelName,id:userId} ) + await logActivity(req,4,{name:'organization Examiner',id:userId} ) res.status(StatusCodes.OK).json({ status: "success", diff --git a/server/controller/organization/joinOrganization.js b/server/controller/organization/joinOrganization.js index d892b24..e61fb1e 100644 --- a/server/controller/organization/joinOrganization.js +++ b/server/controller/organization/joinOrganization.js @@ -51,7 +51,7 @@ exports.joinOrganization = catchAsync(async (req, res, next) => { message: `User with id ${userId} has requested to join the organization `, }); - await logActivity(req,7,{name:organization?.modelName,id:organization.id} ) + await logActivity(req,7,{name:'Organization',id:organization.id} ) res.status(StatusCodes.OK).json({ status: "success", diff --git a/server/controller/organization/updateOrganizationLogo.js b/server/controller/organization/updateOrganizationLogo.js index 21c3309..b18b6f6 100644 --- a/server/controller/organization/updateOrganizationLogo.js +++ b/server/controller/organization/updateOrganizationLogo.js @@ -38,7 +38,7 @@ exports.updateOrganizationLogo = catchAsync(async (req, res, next) => { organization.logo = logo; await organization.save(); - await logActivity(req,1,{name:organization?.modelName,id:organization.id} ) + await logActivity(req,1,{name:'Organization',id:organization.id} ) res.status(StatusCodes.CREATED).json({ status: "success", diff --git a/server/models/log.model.js b/server/models/log.model.js index c93c6f7..8a80d71 100644 --- a/server/models/log.model.js +++ b/server/models/log.model.js @@ -20,7 +20,7 @@ const logSchema = new mongoose.Schema({ default:'none' }, id:{ - type:mongoose.Schema.Types.ObjectId + type:String } } }, diff --git a/server/utils/logActivity.js b/server/utils/logActivity.js index d8be750..8294cf0 100644 --- a/server/utils/logActivity.js +++ b/server/utils/logActivity.js @@ -5,9 +5,10 @@ const actionTypes = ["created","edited","archived","loggedIn","deactivated", "de const logActivity = async (req,actionIndex, {name,id}) => { + console.log(req.user.id) await Log.create({ - user: req.user.id? req.user._id : 'Unknown', - ipAddress: req.ip? req.ip : 'Unknown', + user: req.user.id? req.user.id : 'Unknown', + ipAddress: req .ip? req.ip : 'Unknown', action:`${actionTypes[actionIndex]}`, entity:{ name, From bebcaf33faf023fc0f8344ec170626fecb2d2f7f Mon Sep 17 00:00:00 2001 From: Yohannes Teshome <83913756+johannesteshome@users.noreply.github.com> Date: Fri, 7 Jun 2024 12:33:23 +0300 Subject: [PATCH 03/59] landing page route done --- client/package-lock.json | 534 +----------------- client/src/Components/NavBar.jsx | 10 +- .../src/Screens/LandingPageScreens/About.jsx | 7 +- .../Screens/LandingPageScreens/Customers.jsx | 7 +- .../src/Screens/LandingPageScreens/Home.jsx | 45 +- client/tests/example.spec.js | 2 +- 6 files changed, 62 insertions(+), 543 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index c577057..8fef2bf 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -514,336 +514,6 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "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" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "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" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "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" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "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" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "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" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "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" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "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" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "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" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "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" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "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" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, "node_modules/@esbuild/win32-x64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", @@ -1197,15 +867,6 @@ "node": ">=14" } }, - "node_modules/@rc-component/async-validator": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", - "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", - "dependencies": { - "@babel/runtime": "^7.24.4" - }, - "engines": { - "node": ">=14.x" "node_modules/@playwright/test": { "version": "1.44.1", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.44.1.tgz", @@ -1221,6 +882,17 @@ "node": ">=16" } }, + "node_modules/@rc-component/async-validator": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@rc-component/async-validator/-/async-validator-5.0.4.tgz", + "integrity": "sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==", + "dependencies": { + "@babel/runtime": "^7.24.4" + }, + "engines": { + "node": ">=14.x" + } + }, "node_modules/@rc-component/color-picker": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.3.tgz", @@ -1525,150 +1197,6 @@ "node": ">=14.0.0" } }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", @@ -4147,19 +3675,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5962,20 +5477,6 @@ "node": ">=16" } }, - "node_modules/playwright/node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -8321,7 +7822,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "devOptional": true + }, "node_modules/unicode-properties": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/unicode-properties/-/unicode-properties-1.4.1.tgz", @@ -8344,12 +7850,6 @@ "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==" - - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "devOptional": true }, "node_modules/unload": { "version": "2.2.0", diff --git a/client/src/Components/NavBar.jsx b/client/src/Components/NavBar.jsx index fda3012..995b516 100644 --- a/client/src/Components/NavBar.jsx +++ b/client/src/Components/NavBar.jsx @@ -11,7 +11,7 @@ import fetena_logo from "../assets/fetena_logo.png" import Hamburger from "hamburger-react" -const NavBar = () => { +const NavBar = ({displayPage, setDisplayPage}) => { const [isOpen, setOpen] = useState(false) @@ -59,6 +59,7 @@ const NavBar = () => {