From 589b846761025ae1e87feda6880f2b9e4e222b85 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 15:26:28 +0530 Subject: [PATCH 01/63] feat: change start script --- client/src/App.css | 12 +++++ client/src/components/Nabar/Navbar.jsx | 2 +- client/src/pages/UserPages/Login/Login.jsx | 2 +- server/package.json | 53 +++++++++++----------- server/routes/adminCommunity.js | 7 +++ server/routes/adminRoute.js | 2 + 6 files changed, 50 insertions(+), 28 deletions(-) create mode 100644 server/routes/adminCommunity.js diff --git a/client/src/App.css b/client/src/App.css index b5c61c9..7687335 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -1,3 +1,15 @@ @tailwind base; @tailwind components; @tailwind utilities; + +*::-webkit-scrollbar-track { + background: #291f3a; + } + *::-webkit-scrollbar { + background: transparent; + width: 5px; + } + *::-webkit-scrollbar-thumb { + background: #573174; + border-radius: 20px; + } diff --git a/client/src/components/Nabar/Navbar.jsx b/client/src/components/Nabar/Navbar.jsx index 3ceb4cd..455a440 100644 --- a/client/src/components/Nabar/Navbar.jsx +++ b/client/src/components/Nabar/Navbar.jsx @@ -32,7 +32,7 @@ export default function Navbar() { return ( <> -
+
diff --git a/client/src/pages/UserPages/Login/Login.jsx b/client/src/pages/UserPages/Login/Login.jsx index 968e2ca..efb0c72 100644 --- a/client/src/pages/UserPages/Login/Login.jsx +++ b/client/src/pages/UserPages/Login/Login.jsx @@ -85,7 +85,7 @@ export default function Login() { return ( <> -
+
diff --git a/server/package.json b/server/package.json index f0e020a..2a9a3c6 100644 --- a/server/package.json +++ b/server/package.json @@ -1,28 +1,29 @@ { - "name": "server", - "version": "1.0.0", - "description": "", - "main": "app.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "nodemon app.js" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "bcrypt": "^5.1.1", - "cookie-parser": "^1.4.6", - "cors": "^2.8.5", - "dotenv": "^16.4.5", - "express": "^4.18.3", - "jsonwebtoken": "^9.0.2", - "mongoose": "^8.2.1", - "morgan": "^1.10.0", - "nodemailer": "^6.9.11", - "nodemon": "^3.1.0" - }, - "devDependencies": { - "eslint": "^8.57.0" - } + "name": "server", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "dev": "nodemon app.js", + "start": "node app.js" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "bcrypt": "^5.1.1", + "cookie-parser": "^1.4.6", + "cors": "^2.8.5", + "dotenv": "^16.4.5", + "express": "^4.18.3", + "jsonwebtoken": "^9.0.2", + "mongoose": "^8.2.1", + "morgan": "^1.10.0", + "nodemailer": "^6.9.11", + "nodemon": "^3.1.0" + }, + "devDependencies": { + "eslint": "^8.57.0" + } } diff --git a/server/routes/adminCommunity.js b/server/routes/adminCommunity.js new file mode 100644 index 0000000..a0fcf80 --- /dev/null +++ b/server/routes/adminCommunity.js @@ -0,0 +1,7 @@ +const express = require('express'); +const { isAdminLogedIn } = require('../middlewares/authMiddleware'); +const router = express.Router(); + +router.get('/',isAdminLogedIn,) + +module.exports = router; \ No newline at end of file diff --git a/server/routes/adminRoute.js b/server/routes/adminRoute.js index 7239525..4e33dfc 100644 --- a/server/routes/adminRoute.js +++ b/server/routes/adminRoute.js @@ -2,6 +2,8 @@ const express = require('express'); const router = express.Router(); const adminRightsRoute = require('./adminRightsRoute') const adminBodyRoute = require('./adminBodyRoute') +const adminCommunity = require('./adminCommunity') router.use('/rights', adminRightsRoute) router.use('/my-body', adminBodyRoute) +router.use('/community', adminCommunity) module.exports = router; \ No newline at end of file From c5961d292269e8167ae8adf10fda50bfd0bd4368 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 15:28:52 +0530 Subject: [PATCH 02/63] fix: route protection bug fixed --- client/src/components/Auth/Authenticate.jsx | 2 +- client/src/routes/UserRoute.jsx | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/src/components/Auth/Authenticate.jsx b/client/src/components/Auth/Authenticate.jsx index 38f2d6a..119dcb3 100644 --- a/client/src/components/Auth/Authenticate.jsx +++ b/client/src/components/Auth/Authenticate.jsx @@ -10,7 +10,7 @@ export default function Authenticate() { if (parseUser?.role === "ADMIN") { navigate("/admin"); } else if (parseUser?.role === "USER") { - navigate("/"); + navigate("/home"); } }, [parseUser, navigate]); return <>{!user ? : null}; diff --git a/client/src/routes/UserRoute.jsx b/client/src/routes/UserRoute.jsx index ce22194..5dbc6de 100644 --- a/client/src/routes/UserRoute.jsx +++ b/client/src/routes/UserRoute.jsx @@ -2,6 +2,7 @@ import { lazy, Suspense } from "react"; import { Route, Routes } from "react-router"; import Loader from "../components/Loader/Loader1/Loader"; import Authenticate from "../components/Auth/Authenticate"; +import Protect from "../components/Auth/Protect"; const Home = lazy(() => import("../pages/UserPages/Home/Home")); const Signup = lazy(() => import("../pages/UserPages/Signup/Signup")); @@ -12,11 +13,14 @@ export default function UserRoute() { <> }> - } /> }> + } /> } /> } /> + }> + } /> + From e175425cca909c212fed07907ed87a74e8dc095a Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 15:38:08 +0530 Subject: [PATCH 03/63] removed the currect toxicity bot submodule --- .gitmodules | 3 --- toxicity-bot | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 toxicity-bot diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b4a359c..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "toxicity-bot"] - path = toxicity-bot - url = git@github.com:izam-mohammed/toxicity-bot.git diff --git a/toxicity-bot b/toxicity-bot deleted file mode 160000 index 98f5caf..0000000 --- a/toxicity-bot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 98f5caf22319e489fe979ea8e118dea9531976ac From fb5ba77a88f28da055c9196dffcc76e1f09aebf3 Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 15:38:54 +0530 Subject: [PATCH 04/63] feat: added the talia-bot submodule --- .gitmodules | 3 +++ talia-bot | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 talia-bot diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..01a7912 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "talia-bot"] + path = talia-bot + url = https://github.com/Auto-Playground/talia-bot.git diff --git a/talia-bot b/talia-bot new file mode 160000 index 0000000..8fce0e7 --- /dev/null +++ b/talia-bot @@ -0,0 +1 @@ +Subproject commit 8fce0e74202d2ca9609d1be953aaa7ad3276a2a7 From 646f9b798b6b02846663ff546155361068c2955a Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sat, 9 Mar 2024 16:52:10 +0530 Subject: [PATCH 05/63] feat: admin rights managment in client pages --- client/src/pages/AdminPages/Rights/Rights.jsx | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 client/src/pages/AdminPages/Rights/Rights.jsx diff --git a/client/src/pages/AdminPages/Rights/Rights.jsx b/client/src/pages/AdminPages/Rights/Rights.jsx new file mode 100644 index 0000000..64130f4 --- /dev/null +++ b/client/src/pages/AdminPages/Rights/Rights.jsx @@ -0,0 +1,136 @@ +import { useEffect, useState } from "react"; +import AddRight from "../../../components/AddRight/AddRight"; +import EditRight from "../../../components/EditRight/EditRight"; +import { getRight } from "../../../Services/rightServices"; +import { getDelete } from "../../../Services/rightServices"; +import timeFormat from "../../../utils/timeFormat"; +import { toast } from "react-toastify"; + +function Rights() { + const [openModal, setOpenModal] = useState(false); + const [rightDetails, setRightDetails] = useState([]); + + const [editRight, setEditRight] = useState(); + const [editModal, setEditModal] = useState(false); + + const handleModal = () => { + setOpenModal(true); + }; + const handleEditModal = (rightId) => { + setEditModal(true); + const rightToEdit = rightDetails.find((right) => { + return right?._id === rightId; + }); + setEditRight(rightToEdit); + }; + useEffect(() => { + console.log("Runnning.."); + const getRights = async () => { + const response = await getRight(); + setRightDetails(response.rights); + }; + getRights(); + }, [ + setOpenModal, + setEditModal, + openModal, + editModal, + setRightDetails, + setEditRight, + ]); + const handleDelete = async (rightId) => { + const response = await getDelete(rightId); + if (response.success === true) { + setRightDetails((prevDetails) => + prevDetails.filter((right) => right._id !== rightId) + ); + toast.success(response.message); + } + }; + return ( + <> + + +
+
+ {/* Text Components */} +
+
+

Rights Management

+
+
+ +
+
+ {/* Table Component */} +
+ <> + + + + + + + + + + {rightDetails.map((right, index) => { + return ( + <> + + + + + + + + + + ); + })} +
+ No + + Name + + Date + + Edit or Delete +
+ {index + 1} + {right?.name} + {timeFormat(right?.createdAt)} + + + +
+ +
+
+
+ + ); +} +export default Rights; From 0847f2c02ec2fbc5516c8c2f7eff80fe7847bce8 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sat, 9 Mar 2024 16:53:35 +0530 Subject: [PATCH 06/63] feat: added the api calls for rights components --- client/src/components/AddRight/AddRight.jsx | 35 ++++++--------- client/src/components/EditRight/EditRight.jsx | 44 ++++++++++++------- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/client/src/components/AddRight/AddRight.jsx b/client/src/components/AddRight/AddRight.jsx index e9e8d38..d1d826a 100644 --- a/client/src/components/AddRight/AddRight.jsx +++ b/client/src/components/AddRight/AddRight.jsx @@ -1,12 +1,13 @@ import { useState } from "react"; import { Modal } from "flowbite-react"; import { createRight } from "../../Services/rightServices"; +import { toast } from "react-toastify"; // eslint-disable-next-line react/prop-types function AddRight({ setOpenModal, openModal }) { const [formData, setFormData] = useState({ - right_name: "", - right_desc: "", + name: "", + content: "", }); const handleChange = (e) => { const { name, value } = e.target; @@ -17,13 +18,18 @@ function AddRight({ setOpenModal, openModal }) { }; const handleCreate = async () => { - if (!formData.right_name || !formData.right_desc) { + if (!formData.name || !formData.content) { console.log("Data fields Missing"); return; } try { const response = await createRight(formData); - console.log("response in the page", response); + if (response.success === true) { + formData.name = ""; + formData.content = ""; + toast.success(response.message); + setOpenModal(false); + } } catch (error) { console.log("Error occurred", error); } @@ -42,9 +48,9 @@ function AddRight({ setOpenModal, openModal }) {
@@ -52,27 +58,14 @@ function AddRight({ setOpenModal, openModal }) { - {/*
- - -
*/}
@@ -45,8 +56,8 @@ function EditRight({ setOpenModal, openModal, rightDetails }) {
- From 8e1bfe3f91ddd6ad65cec4a0d4fa19beb9251bfa Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sat, 9 Mar 2024 16:54:45 +0530 Subject: [PATCH 07/63] feat: Admin right services added --- client/src/Services/rightServices.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/Services/rightServices.js b/client/src/Services/rightServices.js index 2593405..ef248e2 100644 --- a/client/src/Services/rightServices.js +++ b/client/src/Services/rightServices.js @@ -8,8 +8,10 @@ export const createRight = async (rightDetails) => { return error; } } -export const updateRight = async (rightDetails, rightId) => { +export const editRight = async (rightDetails, rightId) => { try { + console.log("details", rightDetails) + console.log("right id", rightId) const response = await thaliaAPI.put(`/admin/rights/${rightId}`, rightDetails, { withCredentials: true }); return response.data; } catch (error) { From 196940fe51c30f3a743893c46f9df6eccf6eca29 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sat, 9 Mar 2024 17:02:09 +0530 Subject: [PATCH 08/63] feat: admin time formatter added --- client/src/pages/AdminPages/Rights/Rights.tsx | 98 ------------------- client/src/utils/timeFormat.js | 6 ++ 2 files changed, 6 insertions(+), 98 deletions(-) delete mode 100644 client/src/pages/AdminPages/Rights/Rights.tsx create mode 100644 client/src/utils/timeFormat.js diff --git a/client/src/pages/AdminPages/Rights/Rights.tsx b/client/src/pages/AdminPages/Rights/Rights.tsx deleted file mode 100644 index 78f812f..0000000 --- a/client/src/pages/AdminPages/Rights/Rights.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import React, { useEffect, useState } from "react"; -import AddRight from "../../../components/AddRight/AddRight"; -import EditRight from "../../../components/EditRight/EditRight"; -import { getRight } from "../../../Services/rightServices"; -import { getDelete } from "../../../Services/rightServices"; - -function Rights() { - const [openModal, setOpenModal] = useState(false); - const [rightDetails, setRightDetails] = useState(); - const handleModal = () => { - setOpenModal(true); - }; - useEffect(() => { - const getRights = async () => { - const response = await getRight(); - console.log("This is the response", response); - }; - }, []); - const handleDelete = async (rightId: string) => { - const response = await getDelete(rightId); - }; - return ( - <> - - -
-
- {/* Text Components */} -
-
-

Rights Management

-
-
- -
-
- {/* Table Component */} -
- - - - - - - - - - - - - - - - - -
- No - - Name - - Date - - Edit or Delete -
- 1 - Women Council Act 30418-03-2003 - - -
-
-
-
- - ); -} -export default Rights; diff --git a/client/src/utils/timeFormat.js b/client/src/utils/timeFormat.js new file mode 100644 index 0000000..47ccf08 --- /dev/null +++ b/client/src/utils/timeFormat.js @@ -0,0 +1,6 @@ +const timeFormat = (mongoDate) => { + const date = new Date(mongoDate); + const options = { month: '2-digit', day: '2-digit', year: 'numeric' }; + return date.toLocaleDateString('en-US', options); +} +export default timeFormat; \ No newline at end of file From dd7a942542982b10b21ef650c90d4cea65ac9433 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 19:34:36 +0530 Subject: [PATCH 09/63] feat: added pagination and search added --- server/controller/adminCommunity.js | 82 +++++++++++++++++++++++++++++ server/controller/myBody.js | 10 ++-- server/controller/myRights.js | 8 ++- server/routes/adminCommunity.js | 5 +- 4 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 server/controller/adminCommunity.js diff --git a/server/controller/adminCommunity.js b/server/controller/adminCommunity.js new file mode 100644 index 0000000..3d2c4d2 --- /dev/null +++ b/server/controller/adminCommunity.js @@ -0,0 +1,82 @@ +// const Members = require('../models/membersModel') +const Community = require('../models/communityModel') + +/** + * @desc request for fetching all community + * @route GET /api/admin/community + * @access private + */ + +const getCommunity = async (req, res, next) => { + try { + const community = await Community.aggregate([ + { + $lookup: { + from: "members", + localField: "_id", + foreignField: "community_id", + as: "members" + } + } + ]) + res.status(200).json({ + success: true, + message: "all communities fetched", + community + }) + } catch (error) { + next(error.message); + } +} + +/** + * @desc request for blocking community + * @route PUT /api/admin/community/block/:id + * @access private + */ + +const blockCommunity = async (req, res, next) => { + try { + if (!req.params.id) { + res.status(400); + throw new Error('invalid community id'); + } + const community = await Community.findOneAndUpdate({ _id: req.params.id }, { $set: { id_delete: true } }, { new: true }) + res.status(200).json({ + success: true, + message: "community blocked", + community + }) + } catch (error) { + next(error.message); + } +} + +/** + * @desc request for unblocking community + * @route PUT /api/admin/community/unblock/:id + * @access private + */ + +const unblockCommunity = async (req, res, next) => { + try { + if (!req.params.id) { + res.status(400); + throw new Error('invalid community id'); + } + const community = await Community.findOneAndUpdate({ _id: req.params.id }, { $set: { id_delete: false } }, { new: true }) + res.status(200).json({ + success: true, + message: "community unblocked", + community + }) + } catch (error) { + next(error.message); + } +} + +module.exports = { + getCommunity, + blockCommunity, + unblockCommunity +} \ No newline at end of file diff --git a/server/controller/myBody.js b/server/controller/myBody.js index 66ee7ae..6a3f853 100644 --- a/server/controller/myBody.js +++ b/server/controller/myBody.js @@ -2,16 +2,20 @@ const MyBody = require('../models/myBodyModel') /** * @desc request fetching all content - * @route GET /api/admin/my-body + * @route GET /api/admin/my-body?page=1&&search='aa' * @access private */ const getContents = async (req, res, next) => { try { - const contents = await MyBody.find(); + const page = req.query.page; + const search = req.query.search + const count = await MyBody.countDocuments() + const contents = await MyBody.find({ name: { $regex: new RegExp(search, 'i') } }).skip((page - 1) * 10).limit(10); res.status(200).json({ success: true, message: 'all contents fetched', - contents + contents, + count }) } catch (error) { next(error.message); diff --git a/server/controller/myRights.js b/server/controller/myRights.js index 020aee7..0403d8a 100644 --- a/server/controller/myRights.js +++ b/server/controller/myRights.js @@ -7,11 +7,15 @@ const Rights = require('../models/rightsModel') */ const getRights = async (req, res, next) => { try { - const rights = await Rights.find(); + const page = req.query.page; + const search = req.query.search + const count = await Rights.countDocuments() + const rights = await Rights.find({ name: { $regex: new RegExp(search, 'i') } }).skip((page - 1) * 10).limit(10); res.status(200).json({ success: true, message: 'all rights fetched', - rights + rights, + count }) } catch (error) { next(error.message); diff --git a/server/routes/adminCommunity.js b/server/routes/adminCommunity.js index a0fcf80..fedeb34 100644 --- a/server/routes/adminCommunity.js +++ b/server/routes/adminCommunity.js @@ -1,7 +1,10 @@ const express = require('express'); const { isAdminLogedIn } = require('../middlewares/authMiddleware'); +const { getCommunity, blockCommunity, unblockCommunity } = require('../controller/adminCommunity') const router = express.Router(); -router.get('/',isAdminLogedIn,) +router.get('/', isAdminLogedIn, getCommunity) +router.put('/block/:id', isAdminLogedIn, blockCommunity) +router.put('/unblock/:id', isAdminLogedIn, unblockCommunity) module.exports = router; \ No newline at end of file From 1931db90e6e51289bd20e1219f67704c8055f3c5 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 19:37:23 +0530 Subject: [PATCH 10/63] feat: added demo chat reply --- server/routes/userRoute.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/server/routes/userRoute.js b/server/routes/userRoute.js index 9ba962c..87c5aed 100644 --- a/server/routes/userRoute.js +++ b/server/routes/userRoute.js @@ -3,8 +3,8 @@ const router = express.Router(); const { signup, verifyMail, verifyOtp, signin } = require('../controller/authController'); const profileRoute = require('./profileRoute') const userRightsRoute = require('./userRightsRoute') -const userMyBodyRoute = require('./userMyBodyRoute') -const communityRoute = require('./communityRoute') +const userMyBodyRoute = require('./userMyBodyRoute') +const communityRoute = require('./communityRoute') //authentication router.post('/signup', signup) router.post('/verify-mail', verifyMail) @@ -16,4 +16,11 @@ router.use('/rights', userRightsRoute) router.use('/my-body', userMyBodyRoute) router.use('/community', communityRoute) +router.post('/chat', (req, res) => { + res.status(200).json({ + success: true, + message: "this is the response for " + req.body.query.slice(0, 10) + }) +}) + module.exports = router; \ No newline at end of file From 2f86e757dbb2a9848146efc1c03b2a2b50ac273a Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 19:50:59 +0530 Subject: [PATCH 11/63] fix: removed the broken thalia bot ai bot server --- .gitmodules | 3 --- talia-bot | 1 - 2 files changed, 4 deletions(-) delete mode 100644 .gitmodules delete mode 160000 talia-bot diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 01a7912..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "talia-bot"] - path = talia-bot - url = https://github.com/Auto-Playground/talia-bot.git diff --git a/talia-bot b/talia-bot deleted file mode 160000 index 8fce0e7..0000000 --- a/talia-bot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8fce0e74202d2ca9609d1be953aaa7ad3276a2a7 From 2a369cf985d891de4881058a8281d15bce05b8af Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 20:00:46 +0530 Subject: [PATCH 12/63] chore: removed unneccessory versal file --- server/vercel.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 server/vercel.json diff --git a/server/vercel.json b/server/vercel.json deleted file mode 100644 index 0213a9c..0000000 --- a/server/vercel.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "version": 2, - "builds": [ - { - "src": "app.js", - "use": "@now/node" - } - ], - "routes": [ - { - "src": "/(.*)", - "dest": "app.js" - } - ] -} From e6b4ef55c94b6171f6f58e3a599cade362ef9500 Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 20:01:00 +0530 Subject: [PATCH 13/63] feat: added the Makefile --- Makefile | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e1735aa --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +# Variables +NODE_MODULES=./server/node_modules +DJANGO_VENV=./ai_server/venv + +# Targets +.PHONY: all install_server install_client install_ai_server clean + +all: install_server install_client install_ai_server + +install_server: + @echo "Installing server dependencies..." + cd server && npm install + +install_client: + @echo "Installing client dependencies..." + cd client && npm install + +install_ai_server: + @echo "Setting up Django virtual environment and installing dependencies..." + cd ai_server && python3 -m venv venv && \ + $(DJANGO_VENV)/bin/pip install -r requirements.txt + +clean: + @echo "Cleaning up dependencies..." + @git clean -xdf + rm -rf $(NODE_MODULES) $(DJANGO_VENV) From 37545dfb77102e901aa2180a378e870d0797f9db Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 20:16:57 +0530 Subject: [PATCH 14/63] docs: fixed the broken links in md files --- CONTRIBUTING.md | 4 ++-- LICENSE | 2 +- README.md | 7 +++---- ai_server/README.md | 9 +++++---- client/README.md | 5 +++-- server/README.md | 5 +++-- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cae3a69..d601203 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,11 +6,11 @@ Thank you for considering contributing to Thalia! By participating in this proje ### Reporting Bugs -If you encounter a bug or unexpected behavior, please ensure it hasn't already been reported by checking the [existing issues](https://github.com/izam-mohammed/thalia/issues). If not, create a new issue and include as much detail as possible, including steps to reproduce the bug. +If you encounter a bug or unexpected behavior, please ensure it hasn't already been reported by checking the [existing issues](https://github.com/Auto-Playground/thalia/issues). If not, create a new issue and include as much detail as possible, including steps to reproduce the bug. ### Suggesting Enhancements -If you have ideas for new features or improvements, feel free to submit them as [GitHub issues](https://github.com/izam-mohammed/thalia/issues) labeled with the "enhancement" tag. Provide a clear description of the enhancement and why you believe it would be valuable. +If you have ideas for new features or improvements, feel free to submit them as [GitHub issues](https://github.com/Auto-Playground/thalia/issues) labeled with the "enhancement" tag. Provide a clear description of the enhancement and why you believe it would be valuable. ### Pull Requests diff --git a/LICENSE b/LICENSE index 261eeb9..b8fa607 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright 2024 Auto-Playground Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 0d554b9..7b07306 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,10 @@ Thalia is a cutting-edge website designed to empower women in every aspect of th ## Technologies Used -- **Frontend:** React.js, TailwindCSS, Redux -- **Backend:** Express.js, Node.js +- **Frontend:** React.js, TailwindCSS, Redux @hosted at [thalia.vercel.app](https://thalia.vercel.app/) +- **Backend:** Express.js, Node.js @hosted at [thalia-server.onrender.com](https://thalia-server.onrender.com/) - **Database:** MongoDB -- **Chat Bot:** Django Rest API +- **Chat Bot:** Django Rest API @hosted ai [thalia-ai-server.vercel.app](https://thalia-ai-server.vercel.app/) - **AI models:** Huggingface and OpenAI ## Core Contributers @@ -82,7 +82,6 @@ Thalia is a cutting-edge website designed to empower women in every aspect of th -## Deployment Thalia is successfully hosted on Vercel. You can access the live site [thalia.vercel.app](https://thalia.vercel.app/). diff --git a/ai_server/README.md b/ai_server/README.md index e0c2357..3d876b3 100644 --- a/ai_server/README.md +++ b/ai_server/README.md @@ -1,4 +1,5 @@ -# AI Server 🤖 [[Thalia](https://github.com/izam-mohammed/thalia)] +# AI Server 🤖 [[Thalia](https://github.com/Auto-Playground/thalia)] +@hosted ai [thalia-ai-server.vercel.app](https://thalia-ai-server.vercel.app/) Welcome to the Thalia AI Server repository! This folder contains all the code for the Django server that provides chat functionality for the Thalia web app. The server is built with Django Rest Framework and integrates LangChain and OpenAI LLM for chat capabilities. @@ -15,7 +16,7 @@ Welcome to the Thalia AI Server repository! This folder contains all the code fo 1. Clone the repository: ```bash -git clone +git clone https://github.com/Auto-Playground/thalia cd ai_server ``` @@ -29,8 +30,8 @@ pip install -r requirements.txt ```bash # Create a .env file in the ai_server directory and add the following: -SECRET_KEY= -DEBUG= +HF_TOKEN= +OPENAI_API_KEY= ``` 4. Run database migrations: diff --git a/client/README.md b/client/README.md index 94da119..fab2293 100644 --- a/client/README.md +++ b/client/README.md @@ -1,4 +1,5 @@ -# Client [[Thalia](https://github.com/izam-mohammed/thalia)] +# Client [[Thalia](https://github.com/Auto-Playground/thalia)] +@hosted at [thalia.vercel.app](https://thalia.vercel.app/) Welcome to the Thalia frontend repository! This folder contains all the code for the frontend of our website, including both the user interface and the admin panel. Thalia is built with React.js and utilizes various libraries and tools for enhanced development. @@ -16,7 +17,7 @@ Welcome to the Thalia frontend repository! This folder contains all the code for 1. Clone the repository: ```bash -git clone https://github.com/izam-mohammed/thalia.git +git clone https://github.com/Auto-Playground/thalia cd client ``` diff --git a/server/README.md b/server/README.md index 584c2a1..c754727 100644 --- a/server/README.md +++ b/server/README.md @@ -1,4 +1,5 @@ -# Server [[Thalia](https://github.com/izam-mohammed/thalia)] +# Server [[Thalia](https://github.com/Auto-Playground/thalia)] +@hosted at [thalia-server.onrender.com](https://thalia-server.onrender.com/) Welcome to the Thalia server repository! This folder contains all the code for the backend of our website, including APIs, database configurations, and other server-side logic. Thalia server is built with Express.js and utilizes MongoDB as the database. @@ -16,7 +17,7 @@ Welcome to the Thalia server repository! This folder contains all the code for t 1. Clone the repository: ```bash -git clone https://github.com/izam-mohammed/thalia +git clone https://github.com/Auto-Playground/thalia cd server ``` From 7a691e4bbc0550cdfa54d313840041c13ffa0f8e Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sat, 9 Mar 2024 21:11:04 +0530 Subject: [PATCH 15/63] feat: added the toxicity for the ai bot --- ai_server/ai_server/settings.py | 1 + ai_server/ai_server/urls.py | 3 +- ai_server/chat/llm_call.py | 33 +++++++++---- ai_server/chat/urls.py | 3 +- ai_server/chat/views.py | 7 --- ai_server/toxicity/__init__.py | 0 ai_server/toxicity/admin.py | 3 ++ ai_server/toxicity/apps.py | 6 +++ ai_server/toxicity/hf_call.py | 57 +++++++++++++++++++++++ ai_server/toxicity/migrations/__init__.py | 0 ai_server/toxicity/models.py | 3 ++ ai_server/toxicity/tests.py | 3 ++ ai_server/toxicity/urls.py | 6 +++ ai_server/toxicity/views.py | 39 ++++++++++++++++ 14 files changed, 145 insertions(+), 19 deletions(-) create mode 100644 ai_server/toxicity/__init__.py create mode 100644 ai_server/toxicity/admin.py create mode 100644 ai_server/toxicity/apps.py create mode 100644 ai_server/toxicity/hf_call.py create mode 100644 ai_server/toxicity/migrations/__init__.py create mode 100644 ai_server/toxicity/models.py create mode 100644 ai_server/toxicity/tests.py create mode 100644 ai_server/toxicity/urls.py create mode 100644 ai_server/toxicity/views.py diff --git a/ai_server/ai_server/settings.py b/ai_server/ai_server/settings.py index 8e0ebc8..8b04ffe 100644 --- a/ai_server/ai_server/settings.py +++ b/ai_server/ai_server/settings.py @@ -40,6 +40,7 @@ "rest_framework", "corsheaders", "chat", + "toxicity", ] MIDDLEWARE = [ diff --git a/ai_server/ai_server/urls.py b/ai_server/ai_server/urls.py index 5d9ad7d..a35d787 100644 --- a/ai_server/ai_server/urls.py +++ b/ai_server/ai_server/urls.py @@ -19,7 +19,8 @@ urlpatterns = [ # path("admin/", admin.site.urls), - path("", include("chat.urls")) + path("chat", include("chat.urls")), + path("toxic", include("toxicity.urls")), ] handler404 = "utils.exception_handler.error_404" diff --git a/ai_server/chat/llm_call.py b/ai_server/chat/llm_call.py index 5c52644..9bb5ee6 100644 --- a/ai_server/chat/llm_call.py +++ b/ai_server/chat/llm_call.py @@ -5,26 +5,41 @@ from langchain_core.output_parsers import StrOutputParser from .prompt import PROMPT -def call(input: str) -> Dict[str, Union[bool, str]]: - if "OPENAI_API_KEY" not in os.environ: +def call(user_input: str) -> Dict[str, Union[bool, str]]: + """ + Calls the OpenAI Chat API to generate a response. + + Args: + user_input (str): The input text to generate a response for. + + Returns: + Dict[str, Union[bool, str]]: A dictionary containing the success status and the generated response. + """ + if "OPENAI_API_KEY" not in os.environ or not os.environ["OPENAI_API_KEY"]: return { "success": False, - "message": "OpenAI API key not found", - } + "message": "OpenAI API key not found or empty", + } prompt = ChatPromptTemplate.from_template(PROMPT) model = ChatOpenAI(temperature=0) - chain = prompt | model | StrOutputParser() - - response:str = chain.invoke({"prompt": input}) + chain = prompt | model | StrOutputParser() + try: + response: str = chain.invoke({"prompt": user_input}) + except Exception as e: + return { + "success": False, + "message": f"Error in generation: {str(e)}", + } + if not response: return { "success": False, "message": "Error in generation", - } + } return { "success": True, "message": response, - } + } diff --git a/ai_server/chat/urls.py b/ai_server/chat/urls.py index e369ae5..a772ce9 100644 --- a/ai_server/chat/urls.py +++ b/ai_server/chat/urls.py @@ -2,6 +2,5 @@ from . import views urlpatterns = [ - path("", views.home, name="home"), - path('chat', views.index, name="routes"), + path("", views.index, name="chat"), ] \ No newline at end of file diff --git a/ai_server/chat/views.py b/ai_server/chat/views.py index 9585fe0..9cb51bf 100644 --- a/ai_server/chat/views.py +++ b/ai_server/chat/views.py @@ -4,13 +4,6 @@ from rest_framework import status from .llm_call import call as llm_call -@api_view(["GET", "POST"]) -def home(request): - return Response( - {"success":True ,"message":"connected successfully"}, - status=status.HTTP_200_OK - ) - @api_view(["POST"]) def index(request): content: dict = request.data diff --git a/ai_server/toxicity/__init__.py b/ai_server/toxicity/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ai_server/toxicity/admin.py b/ai_server/toxicity/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/ai_server/toxicity/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/ai_server/toxicity/apps.py b/ai_server/toxicity/apps.py new file mode 100644 index 0000000..5b2195d --- /dev/null +++ b/ai_server/toxicity/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class ToxicityConfig(AppConfig): + default_auto_field = "django.db.models.BigAutoField" + name = "toxicity" diff --git a/ai_server/toxicity/hf_call.py b/ai_server/toxicity/hf_call.py new file mode 100644 index 0000000..a14034d --- /dev/null +++ b/ai_server/toxicity/hf_call.py @@ -0,0 +1,57 @@ +from typing import Dict, Union, List +import requests +import os + +RESPONSE_TYPE = Dict[str, Union[str, float]] + + +def _transform_response(response: List[List[RESPONSE_TYPE]]) -> RESPONSE_TYPE: + """ + Transforms the response from the API call. + + Args: + response (List[List[RESPONSE_TYPE]]): The response from the API call. + + Returns: + RESPONSE_TYPE: The transformed response. + """ + if response[0][0]["score"] > response[0][1]["score"]: + return response[0][0] + return response[0][1] + + +def call(text: str) -> RESPONSE_TYPE: + """ + Calls the Hugging Face API to classify toxic comments. + + Args: + text (str): The text to classify. + + Returns: + RESPONSE_TYPE: The response from the API. + """ + if "HF_TOKEN" not in os.environ or not os.environ["HF_TOKEN"]: + return { + "success": False, + "message": "Huggingface Token not found or empty", + } + + HF_TOKEN = os.environ["HF_TOKEN"] + headers = {"Authorization": f"Bearer {HF_TOKEN}"} + api_url = ( + "https://api-inference.huggingface.co/models/martin-ha/toxic-comment-model" + ) + + response = requests.post(api_url, headers=headers, json={"inputs": text}) + + if response.status_code != 200: + return { + "success": False, + "message": f"API returned status code {response.status_code}", + } + + response_data = response.json() + transformed_response = _transform_response(response_data) + transformed_response["success"] = True + + return transformed_response diff --git a/ai_server/toxicity/migrations/__init__.py b/ai_server/toxicity/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/ai_server/toxicity/models.py b/ai_server/toxicity/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/ai_server/toxicity/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/ai_server/toxicity/tests.py b/ai_server/toxicity/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/ai_server/toxicity/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/ai_server/toxicity/urls.py b/ai_server/toxicity/urls.py new file mode 100644 index 0000000..6d2f8a7 --- /dev/null +++ b/ai_server/toxicity/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path("", views.index, name="toxic"), +] \ No newline at end of file diff --git a/ai_server/toxicity/views.py b/ai_server/toxicity/views.py new file mode 100644 index 0000000..1e83572 --- /dev/null +++ b/ai_server/toxicity/views.py @@ -0,0 +1,39 @@ +from typing import Dict, Union +from rest_framework.decorators import api_view +from rest_framework.response import Response +from rest_framework import status +from .hf_call import call as hf_call + +@api_view(["POST"]) +def index(request): + content: dict = request.data + text = content.get("text") + if text is None: + return Response( + {"success": False, "message": "text is required !"}, + status=status.HTTP_400_BAD_REQUEST, + ) + if not isinstance(text, str): + return Response( + {"success": False, "message": "text should be str !"}, + status=status.HTTP_400_BAD_REQUEST, + ) + if not text: + return Response( + {"success": False, "message": "query should not be empty"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + response:Dict[str, Union[bool, str]] = hf_call(text=text) + + if not response["success"]: + return Response( + response, + status=status.HTTP_500_INTERNAL_SERVER_ERROR, + ) + + return Response( + response, + status=status.HTTP_200_OK, + ) + From bc969179ad6eab01161d1914754af7d1be4a0390 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 21:30:57 +0530 Subject: [PATCH 16/63] chore: mui icon external library installed --- client/package-lock.json | 630 +++++++++++++++++++++++++++++++++++++-- client/package.json | 6 + 2 files changed, 616 insertions(+), 20 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index e30fe5c..28e89c2 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -8,18 +8,24 @@ "name": "client", "version": "0.0.0", "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.12", + "@mui/material": "^5.15.12", "@reduxjs/toolkit": "^2.2.1", "axios": "^1.6.7", "flowbite-react": "^0.7.2", "js-cookie": "^3.0.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-markdown": "^9.0.1", "react-redux": "^9.1.0", "react-router-dom": "^6.22.3", "react-toastify": "^10.0.4", "sweetalert2": "^11.10.6" }, "devDependencies": { + "@tailwindcss/typography": "^0.5.10", "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", @@ -70,7 +76,6 @@ "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -187,7 +192,6 @@ "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==", - "dev": true, "dependencies": { "@babel/types": "^7.22.15" }, @@ -251,7 +255,6 @@ "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==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -260,7 +263,6 @@ "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==", - "dev": true, "engines": { "node": ">=6.9.0" } @@ -292,7 +294,6 @@ "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -394,7 +395,6 @@ "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", - "dev": true, "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -962,6 +962,163 @@ "resolved": "https://registry.npmjs.org/@effect-ts/system/-/system-0.57.5.tgz", "integrity": "sha512-/crHGujo0xnuHIYNc1VgP0HGJGFSoSqq88JFXe6FmFyXPpWt8Xu39LyLg7rchsxfXFeEdA9CrIZvLV5eswXV5g==" }, + "node_modules/@emotion/babel-plugin": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", + "dependencies": { + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", + "dependencies": { + "@emotion/memoize": "^0.8.1" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" + }, + "node_modules/@emotion/react": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", + "dependencies": { + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" + }, + "node_modules/@emotion/styled": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" + }, "node_modules/@esbuild-plugins/node-resolve": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-resolve/-/node-resolve-0.1.4.tgz", @@ -1675,6 +1832,261 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz", + "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz", + "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/icons-material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz", + "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==", + "dependencies": { + "@babel/runtime": "^7.23.9" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz", + "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.38", + "@mui/core-downloads-tracker": "^5.15.12", + "@mui/system": "^5.15.12", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/@mui/private-theming": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz", + "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.12", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz", + "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.12", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.12", + "clsx": "^2.1.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz", + "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", + "prop-types": "^15.8.1", + "react-is": "^18.2.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", + "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, "node_modules/@next/env": { "version": "13.5.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.6.tgz", @@ -2623,6 +3035,34 @@ "tslib": "^2.4.0" } }, + "node_modules/@tailwindcss/typography": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", + "integrity": "sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==", + "dev": true, + "dependencies": { + "lodash.castarray": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.merge": "^4.6.2", + "postcss-selector-parser": "6.0.10" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@types/acorn": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", @@ -2727,6 +3167,11 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + }, "node_modules/@types/parse5": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", @@ -2756,6 +3201,14 @@ "@types/react": "*" } }, + "node_modules/@types/react-transition-group": { + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.20.6", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.6.tgz", @@ -2858,7 +3311,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "dependencies": { "color-convert": "^1.9.0" }, @@ -3140,6 +3592,36 @@ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==" }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-macros/node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bail": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", @@ -3353,7 +3835,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -3407,7 +3888,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -3628,7 +4108,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "dependencies": { "color-name": "1.1.3" } @@ -3773,6 +4252,29 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3979,6 +4481,15 @@ "node": ">=6.0.0" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -4008,6 +4519,19 @@ "once": "^1.4.0" } }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "node_modules/es-abstract": { "version": "1.22.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.5.tgz", @@ -4199,7 +4723,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, "engines": { "node": ">=0.8.0" } @@ -4808,6 +5331,11 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -5236,7 +5764,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, "engines": { "node": ">=4" } @@ -6124,6 +6651,14 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/html-url-attributes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.0.tgz", @@ -6191,7 +6726,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -6802,6 +7336,11 @@ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6969,6 +7508,18 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, + "node_modules/lodash.castarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", + "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", + "dev": true + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -9324,7 +9875,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -9351,6 +9901,23 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -9419,6 +9986,14 @@ "node": "14 || >=16.14" } }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "engines": { + "node": ">=8" + } + }, "node_modules/periscopic": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", @@ -9709,7 +10284,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -9890,8 +10464,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-markdown": { "version": "9.0.1", @@ -10597,6 +11170,21 @@ "react-dom": ">=16" } }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -10878,7 +11466,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -11531,6 +12118,11 @@ } } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -11599,7 +12191,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -11757,7 +12348,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, "engines": { "node": ">=4" } diff --git a/client/package.json b/client/package.json index 9ddd412..9f93659 100644 --- a/client/package.json +++ b/client/package.json @@ -10,18 +10,24 @@ "preview": "vite preview" }, "dependencies": { + "@emotion/react": "^11.11.4", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.12", + "@mui/material": "^5.15.12", "@reduxjs/toolkit": "^2.2.1", "axios": "^1.6.7", "flowbite-react": "^0.7.2", "js-cookie": "^3.0.5", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-markdown": "^9.0.1", "react-redux": "^9.1.0", "react-router-dom": "^6.22.3", "react-toastify": "^10.0.4", "sweetalert2": "^11.10.6" }, "devDependencies": { + "@tailwindcss/typography": "^0.5.10", "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", "@vitejs/plugin-react": "^4.2.1", From 17e7642968bbd4399bfad22d00c2b6ca3adc351a Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 21:31:52 +0530 Subject: [PATCH 17/63] style: custom style for pagination added --- client/src/App.css | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/client/src/App.css b/client/src/App.css index 7687335..25b9795 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -3,13 +3,23 @@ @tailwind utilities; *::-webkit-scrollbar-track { - background: #291f3a; - } - *::-webkit-scrollbar { - background: transparent; - width: 5px; - } - *::-webkit-scrollbar-thumb { - background: #573174; - border-radius: 20px; - } + background: #291f3a; +} +*::-webkit-scrollbar { + background: transparent; + width: 5px; +} +*::-webkit-scrollbar-thumb { + background: #573174; + border-radius: 20px; +} + +.mypage button { + background-color: rgb(56, 36, 61); + border-color: rgb(93, 0, 74); +} + +.mypage button:hover { + background-color: rgb(74, 29, 86) !important; + color: rgb(168, 145, 174) !important; +} From f63e727f1e1e951d0e194bd4bf2895e69b8e43f4 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 21:33:19 +0530 Subject: [PATCH 18/63] fix: fixed md file showing problem --- client/tailwind.config.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 3b08ba1..4df0484 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -12,12 +12,15 @@ export default { }, gradientColorStops: { 'custom-gradient': { - 'start': '#e19eb7', - 'end': '#951947', + 'start': '#e19eb7', + 'end': '#951947', }, } }, }, - plugins: [require('flowbite/plugin'),], + plugins: [ + require('flowbite/plugin'), + require('@tailwindcss/typography'), + ], } From 0d08dda49f0b08913b1aaa400111600f545046b4 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 21:34:50 +0530 Subject: [PATCH 19/63] feat: added util functions for search in ui --- client/src/utils/functions.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 client/src/utils/functions.js diff --git a/client/src/utils/functions.js b/client/src/utils/functions.js new file mode 100644 index 0000000..ef8aa35 --- /dev/null +++ b/client/src/utils/functions.js @@ -0,0 +1,9 @@ +export const debounce = (cb, delay = 250) => { + let timeoutId; + return (...args) => { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => { + cb(...args); + }, delay); + }; +} \ No newline at end of file From 011593b4d093d9084587951ba3890f09d0116db0 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sat, 9 Mar 2024 21:36:03 +0530 Subject: [PATCH 20/63] feat: My laws, my Body, my Mind pages added --- client/src/components/UserHome/UserHome.jsx | 21 +++- .../ViewMarkModal/ViewMarkModal.jsx | 38 +++++++ .../pages/UserPages/MyBodyPage/MyBodyPage.jsx | 101 ++++++++++++++++++ .../pages/UserPages/MyLawsPage/MyLawsPage.jsx | 101 ++++++++++++++++++ .../pages/UserPages/MyMindPage/MyMindPage.jsx | 101 ++++++++++++++++++ client/src/routes/UserRoute.jsx | 12 +++ 6 files changed, 369 insertions(+), 5 deletions(-) create mode 100644 client/src/components/ViewMarkModal/ViewMarkModal.jsx create mode 100644 client/src/pages/UserPages/MyBodyPage/MyBodyPage.jsx create mode 100644 client/src/pages/UserPages/MyLawsPage/MyLawsPage.jsx create mode 100644 client/src/pages/UserPages/MyMindPage/MyMindPage.jsx diff --git a/client/src/components/UserHome/UserHome.jsx b/client/src/components/UserHome/UserHome.jsx index 882511d..60f9eb4 100644 --- a/client/src/components/UserHome/UserHome.jsx +++ b/client/src/components/UserHome/UserHome.jsx @@ -2,17 +2,28 @@ import MybodyCard from "../MyBodyCard/MybodyCard"; import MyLawsCard from "../MyLawsCard/MyLawsCard"; import MyMindCard from "../MyMindCard/MyMindCard"; import CommunityCard from "../CommunityCard/CommunityCard"; +import { Link } from "react-router-dom"; export default function UserHome() { return (
- - - + + + + + + + + +
- -
+ +
); } diff --git a/client/src/components/ViewMarkModal/ViewMarkModal.jsx b/client/src/components/ViewMarkModal/ViewMarkModal.jsx new file mode 100644 index 0000000..bf0b38d --- /dev/null +++ b/client/src/components/ViewMarkModal/ViewMarkModal.jsx @@ -0,0 +1,38 @@ +import { Modal } from "flowbite-react"; +import PropTypes from "prop-types"; +import ReactMarkdown from "react-markdown"; + +export default function ViewMarkModal({ + openModal, + setOpenModal, + content, + setContent, +}) { + return ( + <> + { + setContent(""); + setOpenModal(false); + }} + > + {content.name} + + + {content.content} + + + + + ); +} + +ViewMarkModal.propTypes = { + openModal: PropTypes.bool.isRequired, + setOpenModal: PropTypes.func.isRequired, + content: PropTypes.object.isRequired, + setContent: PropTypes.func.isRequired, +}; diff --git a/client/src/pages/UserPages/MyBodyPage/MyBodyPage.jsx b/client/src/pages/UserPages/MyBodyPage/MyBodyPage.jsx new file mode 100644 index 0000000..509cf5f --- /dev/null +++ b/client/src/pages/UserPages/MyBodyPage/MyBodyPage.jsx @@ -0,0 +1,101 @@ +import { useEffect, useState } from "react"; +import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos"; +import SearchIcon from "@mui/icons-material/Search"; +import ViewMarkModal from "../../../components/ViewMarkModal/ViewMarkModal"; +import { Pagination } from "flowbite-react"; +import { Link } from "react-router-dom"; +import { debounce } from "../../../utils/functions"; +import thaliaAPI from "../../../API/thaliaAPI"; + +export default function MyBodyPage() { + const [openModal, setOpenModal] = useState(false); + const [content, setContent] = useState({ name: "", content: "" }); + const [search, setSearch] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const [count, setCount] = useState(0); + + const [contents, setContents] = useState([]); + + useEffect(() => { + (async function () { + try { + const { data } = await thaliaAPI.get( + `/my-body?search=${search}&&page=${currentPage}` + ); + if (data.success) { + setContents(data.contents); + setCount(data.count); + } + } catch (err) { + console.log(err); + } + })(); + }, [search, currentPage]); + + useEffect(() => { + if (content.content && content.name) { + setOpenModal(true); + } + }, [content]); + const onPageChange = (page) => setCurrentPage(page); + const debaunceSearch = debounce((text) => { + setSearch(text); + }, 500); + + return ( + <> + +
+

My Body

+
+ + Back + +
+ debaunceSearch(e.target.value)} + className="h-8 focus:outline-none text-text focus:ring-0 rounded-lg border-0 bg-transparent" + type="text" + placeholder="search" + /> + +
+
+ {contents.length > 0 && + contents.map((e) => { + return ( + <> +
{ + setContent(e); + }} + className="w-full py-4 z-20 px-4 bg-primary/[0.3] hover:bg-secondary rounded-lg cursor-pointer" + > +

{e.name}

+
+ + ); + })} +
+ {count > 0 && ( + + )} +
+ +
+ + ); +} diff --git a/client/src/pages/UserPages/MyLawsPage/MyLawsPage.jsx b/client/src/pages/UserPages/MyLawsPage/MyLawsPage.jsx new file mode 100644 index 0000000..120f34a --- /dev/null +++ b/client/src/pages/UserPages/MyLawsPage/MyLawsPage.jsx @@ -0,0 +1,101 @@ +import { useEffect, useState } from "react"; +import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos"; +import SearchIcon from "@mui/icons-material/Search"; +import ViewMarkModal from "../../../components/ViewMarkModal/ViewMarkModal"; +import { Pagination } from "flowbite-react"; +import { Link } from "react-router-dom"; +import { debounce } from "../../../utils/functions"; +import thaliaAPI from "../../../API/thaliaAPI"; + +export default function MyLawsPage() { + const [openModal, setOpenModal] = useState(false); + const [content, setContent] = useState({ name: "", content: "" }); + const [search, setSearch] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const [count, setCount] = useState(0); + + const [contents, setContents] = useState([]); + + useEffect(() => { + (async function () { + try { + const { data } = await thaliaAPI.get( + `/rights?search=${search}&&page=${currentPage}` + ); + if (data.success) { + setContents(data.rights); + setCount(data.count); + } + } catch (err) { + console.log(err); + } + })(); + }, [search, currentPage]); + + useEffect(() => { + if (content.content && content.name) { + setOpenModal(true); + } + }, [content]); + const onPageChange = (page) => setCurrentPage(page); + const debaunceSearch = debounce((text) => { + setSearch(text); + }, 500); + + return ( + <> + +
+

MY Rights

+
+ + Back + +
+ debaunceSearch(e.target.value)} + className="h-8 focus:outline-none text-text focus:ring-0 rounded-lg border-0 bg-transparent" + type="text" + placeholder="search" + /> + +
+
+ {contents.length > 0 && + contents.map((e) => { + return ( + <> +
{ + setContent(e); + }} + className="w-full py-4 z-20 px-4 bg-primary/[0.3] hover:bg-secondary rounded-lg cursor-pointer" + > +

{e.name}

+
+ + ); + })} +
+ {count > 0 && ( + + )} +
+ +
+ + ); +} diff --git a/client/src/pages/UserPages/MyMindPage/MyMindPage.jsx b/client/src/pages/UserPages/MyMindPage/MyMindPage.jsx new file mode 100644 index 0000000..b671356 --- /dev/null +++ b/client/src/pages/UserPages/MyMindPage/MyMindPage.jsx @@ -0,0 +1,101 @@ +import { useEffect, useState } from "react"; +import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos"; +import SearchIcon from "@mui/icons-material/Search"; +import ViewMarkModal from "../../../components/ViewMarkModal/ViewMarkModal"; +import { Pagination } from "flowbite-react"; +import { Link } from "react-router-dom"; +import { debounce } from "../../../utils/functions"; +import thaliaAPI from "../../../API/thaliaAPI"; + +export default function MyMindPage() { + const [openModal, setOpenModal] = useState(false); + const [content, setContent] = useState({ name: "", content: "" }); + const [search, setSearch] = useState(""); + const [currentPage, setCurrentPage] = useState(1); + const [count, setCount] = useState(0); + + const [mind, setMind] = useState([]); + + useEffect(() => { + (async function () { + try { + const { data } = await thaliaAPI.get( + `/my-mind?search=${search}&&page=${currentPage}` + ); + if (data.success) { + setMind(data.contents); + setCount(data.count); + } + } catch (err) { + console.log(err); + } + })(); + }, [search, currentPage]); + + useEffect(() => { + if (content.content && content.name) { + setOpenModal(true); + } + }, [content]); + const onPageChange = (page) => setCurrentPage(page); + const debaunceSearch = debounce((text) => { + setSearch(text); + }, 500); + + return ( + <> + +
+

MY Mind

+
+ + Back + +
+ debaunceSearch(e.target.value)} + className="h-8 focus:outline-none text-text focus:ring-0 rounded-lg border-0 bg-transparent" + type="text" + placeholder="search" + /> + +
+
+ {mind.length > 0 && + mind.map((e) => { + return ( + <> +
{ + setContent(e); + }} + className="w-full z-20 py-4 px-4 bg-primary/[0.3] hover:bg-secondary rounded-lg cursor-pointer" + > +

{e.name}

+
+ + ); + })} +
+ {count > 0 && ( + + )} +
+ +
+ + ); +} diff --git a/client/src/routes/UserRoute.jsx b/client/src/routes/UserRoute.jsx index 5dbc6de..45ff0e7 100644 --- a/client/src/routes/UserRoute.jsx +++ b/client/src/routes/UserRoute.jsx @@ -7,6 +7,15 @@ import Protect from "../components/Auth/Protect"; const Home = lazy(() => import("../pages/UserPages/Home/Home")); const Signup = lazy(() => import("../pages/UserPages/Signup/Signup")); const Login = lazy(() => import("../pages/UserPages/Login/Login")); +const MyMindPage = lazy(() => + import("../pages/UserPages/MyMindPage/MyMindPage") +); +const MyLawsPage = lazy(() => + import("../pages/UserPages/MyLawsPage/MyLawsPage") +); +const MyBodyPage = lazy(() => + import("../pages/UserPages/MyBodyPage/MyBodyPage") +); export default function UserRoute() { return ( @@ -20,6 +29,9 @@ export default function UserRoute() { }> } /> + } /> + } /> + } /> From 6f159a1d5d117d954c17b9f862f180a4b9f4506a Mon Sep 17 00:00:00 2001 From: Izam Mohammed <106471909+izam-mohammed@users.noreply.github.com> Date: Sat, 9 Mar 2024 21:51:59 +0530 Subject: [PATCH 21/63] Update README.md --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7b07306..bf72801 100644 --- a/README.md +++ b/README.md @@ -57,10 +57,13 @@ Thalia is a cutting-edge website designed to empower women in every aspect of th ## Technologies Used -- **Frontend:** React.js, TailwindCSS, Redux @hosted at [thalia.vercel.app](https://thalia.vercel.app/) -- **Backend:** Express.js, Node.js @hosted at [thalia-server.onrender.com](https://thalia-server.onrender.com/) +- **Frontend:** React.js, TailwindCSS, Redux + > @hosted at [thalia.vercel.app](https://thalia.vercel.app/) +- **Backend:** Express.js, Node.js + > @hosted at [thalia-server.onrender.com](https://thalia-server.onrender.com/) - **Database:** MongoDB -- **Chat Bot:** Django Rest API @hosted ai [thalia-ai-server.vercel.app](https://thalia-ai-server.vercel.app/) +- **Chat Bot:** Django Rest API + > @hosted ai [thalia-ai-server.vercel.app](https://thalia-ai-server.vercel.app/) - **AI models:** Huggingface and OpenAI ## Core Contributers From 71469f19b038d4b12012801a9b9d4a73d6842708 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 22:53:38 +0530 Subject: [PATCH 22/63] feat: added user management --- server/app.js | 2 +- server/controller/adminUser.js | 118 ++++++++++++++++++++++++++++ server/controller/myMind.js | 106 +++++++++++++++++++++++++ server/controller/userController.js | 110 ++++++++++++++++++++++++++ server/models/myMind.js | 14 ++++ server/models/reportsModel.js | 21 +++++ server/routes/adminMindRoute.js | 10 +++ server/routes/adminRoute.js | 4 + server/routes/adminUserRoute.js | 9 +++ server/routes/communityRoute.js | 4 + server/routes/indexRoute.js | 31 ++++++++ server/routes/userMyMindRoute.js | 7 ++ server/routes/userRoute.js | 26 ++---- 13 files changed, 440 insertions(+), 22 deletions(-) create mode 100644 server/controller/adminUser.js create mode 100644 server/controller/myMind.js create mode 100644 server/controller/userController.js create mode 100644 server/models/myMind.js create mode 100644 server/models/reportsModel.js create mode 100644 server/routes/adminMindRoute.js create mode 100644 server/routes/adminUserRoute.js create mode 100644 server/routes/indexRoute.js create mode 100644 server/routes/userMyMindRoute.js diff --git a/server/app.js b/server/app.js index 839fe89..f6442af 100644 --- a/server/app.js +++ b/server/app.js @@ -7,7 +7,7 @@ const morgan = require('morgan') const cookieParser = require('cookie-parser'); const { notFound, errorHandler } = require('./middlewares/errorMiddlewares') -const userRoute = require('./routes/userRoute.js') +const userRoute = require('./routes/indexRoute.js') const adminRoute = require('./routes/adminRoute.js') const ORIGIN = process.env.NODE_ENV === 'development' ? "http://localhost:4000" : 'https://thalia.vercel.app' const corsConfig = { diff --git a/server/controller/adminUser.js b/server/controller/adminUser.js new file mode 100644 index 0000000..728d68d --- /dev/null +++ b/server/controller/adminUser.js @@ -0,0 +1,118 @@ +const User = require('../models/userModel') +// const Profile = require('../models/profileModel') +// const Report = require('../models/reportsModel') + +/** + * @desc request fetching all users + * @route GET /api/admin/users?search + * @access private + */ +const getUserList = async (req, res, next) => { + const search = req.query.search; + try { + const userList = await User.aggregate([ + { + $match: { + role: 'USER' + } + }, + { + $lookup: { + from: "profiles", + localField: '_id', + foreignField: "user_id", + as: "profile" + } + }, + { + $unwind: { + path: '$profile' + } + }, + { + $project: { + email: 1, + role: 1, + is_blocked: 1, + username: "$profile.username", + fullname: "$profile.fullname", + profile_img: "$profile.profile_img", + bio: "$profile.bio" + } + }, + { + $lookup: { + from: "reports", + localField: '_id', + foreignField: "report_id", + as: "reports" + } + }, + { + $match: { + $or: [ + { username: { $regex: new RegExp(search, 'i') } }, + { fullname: { $regex: new RegExp(search, 'i') } } + ], + } + } + ]) + res.status(200).json({ + success: true, + message: "users list fetched", + userList + }) + } catch (error) { + next(error.message) + } +} + +/** + * @desc request for blocking user + * @route GET /api/admin/users/block/:id + * @access private + */ + +const blockUser = async (req, res, next) => { + try { + const block = await User.findOneAndUpdate({ _id: req.params.id }, { $set: { is_blocked: true } }, { new: true }); + if (block.is_blocked) { + res.status(200).json({ + success: true, + message: "user blocked" + }) + } else { + throw new Error("Internal server error") + } + } catch (error) { + next(error.message) + } +} + +/** + * @desc request for unblocking user + * @route GET /api/admin/users/unblock/:id + * @access private + */ + +const unblockUser = async (req, res, next) => { + try { + const block = await User.findOneAndUpdate({ _id: req.params.id }, { $set: { is_blocked: false } }, { new: true }); + if (!block.is_blocked) { + res.status(200).json({ + success: true, + message: "user unblocked" + }) + } else { + throw new Error("Internal server error") + } + } catch (error) { + next(error.message) + } +} + +module.exports = { + getUserList, + blockUser, + unblockUser +} \ No newline at end of file diff --git a/server/controller/myMind.js b/server/controller/myMind.js new file mode 100644 index 0000000..00cff41 --- /dev/null +++ b/server/controller/myMind.js @@ -0,0 +1,106 @@ +const MyMind = require('../models/myMind') + +/** + * @desc request fetching all content + * @route GET /api/admin/my-body?page=1&&search='aa' + * @access private + */ +const getContents = async (req, res, next) => { + try { + const page = req.query.page; + const search = req.query.search + const count = await MyMind.countDocuments() + const contents = await MyMind.find({ name: { $regex: new RegExp(search, 'i') } }).skip((page - 1) * 10).limit(10); + res.status(200).json({ + success: true, + message: 'all contents fetched', + contents, + count + }) + } catch (error) { + next(error.message); + } +} + +/** + * @desc request for creating content + * @route POST /api/admin/my-body + * @access private + */ +const createContent = async (req, res, next) => { + try { + const { name, content } = req.body; + if (!name || !content) { + res.status(400); + throw new Error('Details missing') + } + const newContent = await new MyMind({ + name, content + }).save() + if (newContent) { + res.status(201).json({ + success: true, + message: 'new content created successfully', + newContent + }) + } else { + throw new Error('Internal server error') + } + } catch (error) { + next(error.message); + } +} + +/** + * @desc request for updating content + * @route PUT /api/admin/my-body/:id + * @access private + */ +const updateContent = async (req, res, next) => { + try { + if (!req.params.id) { + res.status(400) + throw new Error('content not found') + } + const content = await MyMind.findOneAndUpdate({ _id: req.params.id }, { $set: { ...req.body } }, { new: true }) + if (content) { + res.status(200).json({ + success: true, + message: 'content updated successfully', + content + }) + } else { + throw new Error('Internal server error') + } + } catch (error) { + next(error.message); + } +} + +/** + * @desc request for deleting content + * @route delete /api/admin/my-body/:id + * @access private + */ +const deleteContent = async (req, res, next) => { + try { + if (!req.params.id) { + res.status(400) + throw new Error('Content not found') + } + await MyMind.findOneAndDelete({ _id: req.params.id }) + res.status(200).json({ + success: true, + message: 'content deleted successfully' + }) + } catch (error) { + next(error.message); + } +} + +module.exports = { + getContents, + createContent, + updateContent, + deleteContent +} \ No newline at end of file diff --git a/server/controller/userController.js b/server/controller/userController.js new file mode 100644 index 0000000..74493d9 --- /dev/null +++ b/server/controller/userController.js @@ -0,0 +1,110 @@ +const User = require('../models/userModel') +const Profile = require('../models/profileModel') +const Report = require('../models/reportsModel') + +/** + * @desc request fetching all users + * @route GET /api/users?search + * @access private + */ +const getUsers = async (req, res, next) => { + const search = req.query.search; + try { + const userList = await User.aggregate([ + { + $match: { + is_blocked: false, + role: 'USER' + } + }, + { + $lookup: { + from: "profiles", + localField: '_id', + foreignField: "user_id", + as: "profile" + } + }, + { + $unwind: { + path: '$profile' + } + }, + { + $project: { + email: 1, + role: 1, + is_blocked: 1, + username: "$profile.username", + fullname: "$profile.fullname", + profile_img: "$profile.profile_img", + bio: "$profile.bio" + } + }, + { + $match: { + $or: [ + { username: { $regex: new RegExp(search, 'i') } }, + { fullname: { $regex: new RegExp(search, 'i') } } + ], + } + } + ]) + res.status(200).json({ + success: true, + message: "users list fetched", + userList + }) + } catch (error) { + next(error.message) + } +} + + +/** + * @desc request fetching user profile + * @route GET /api/users/:id + * @access private + */ +const getUserDetails = async (req, res, next) => { + try { + const userDetails = await Profile.findOne({ user_id: req.params.id }, { _id: 0, username: 1, fullname: 1 }) + res.status(200).json({ + success: true, + message: "user details fetched", + userDetails + }) + } catch (error) { + next(error.message) + } +} + + +/** + * @desc request for report user + * @route GET /api/users/report + * @access private + */ +const reportUser = async (req, res, next) => { + try { + const report = await new Report({ + report_id: req.body.user_id, + reporter_id: req.user._id, + report_type: req.body.report_type, + reason: req.body.reason + }).save() + res.status(200).json({ + success: true, + message: "new report added", + report + }) + } catch (error) { + next(error.message) + } +} + +module.exports = { + getUsers, + getUserDetails, + reportUser +} \ No newline at end of file diff --git a/server/models/myMind.js b/server/models/myMind.js new file mode 100644 index 0000000..cc885bd --- /dev/null +++ b/server/models/myMind.js @@ -0,0 +1,14 @@ +const mongoose = require("mongoose"); + +const myMindSchema = new mongoose.Schema({ + name: { + type: String, + required: true + }, + content: { + type: String, + required: true + }, +}, { timestamps: true }); + +module.exports = mongoose.model("MyMind", myMindSchema); \ No newline at end of file diff --git a/server/models/reportsModel.js b/server/models/reportsModel.js new file mode 100644 index 0000000..51da2f1 --- /dev/null +++ b/server/models/reportsModel.js @@ -0,0 +1,21 @@ +const mongoose = require("mongoose"); + +const reportSchema = new mongoose.Schema({ + report_id: { + type: mongoose.Types.ObjectId, + required: true + }, + reporter_id: { + type: mongoose.Types.ObjectId, + required: true + }, + report_type: { + type: String, + enum: ['USER', 'COMMUNITY'] + }, + reason: { + type: String, + } +}, { timestamps: true }); + +module.exports = mongoose.model("Report", reportSchema); \ No newline at end of file diff --git a/server/routes/adminMindRoute.js b/server/routes/adminMindRoute.js new file mode 100644 index 0000000..ef52987 --- /dev/null +++ b/server/routes/adminMindRoute.js @@ -0,0 +1,10 @@ +const express = require('express'); +const { isAdminLogedIn } = require('../middlewares/authMiddleware'); +const { getContents, createContent, updateContent, deleteContent } = require('../controller/myMind') +const router = express.Router(); + +router.get('/', isAdminLogedIn, getContents) +router.post('/', isAdminLogedIn, createContent) +router.put('/:id', isAdminLogedIn, updateContent) +router.delete('/:id', isAdminLogedIn, deleteContent) +module.exports = router; \ No newline at end of file diff --git a/server/routes/adminRoute.js b/server/routes/adminRoute.js index 4e33dfc..ec4cba9 100644 --- a/server/routes/adminRoute.js +++ b/server/routes/adminRoute.js @@ -3,7 +3,11 @@ const router = express.Router(); const adminRightsRoute = require('./adminRightsRoute') const adminBodyRoute = require('./adminBodyRoute') const adminCommunity = require('./adminCommunity') +const adminMindRoute = require('./adminMindRoute') +const adminUserRoute = require('./adminUserRoute') router.use('/rights', adminRightsRoute) router.use('/my-body', adminBodyRoute) +router.use('/my-mind', adminMindRoute) router.use('/community', adminCommunity) +router.use('/users', adminUserRoute) module.exports = router; \ No newline at end of file diff --git a/server/routes/adminUserRoute.js b/server/routes/adminUserRoute.js new file mode 100644 index 0000000..9fef735 --- /dev/null +++ b/server/routes/adminUserRoute.js @@ -0,0 +1,9 @@ +const express = require('express'); +const router = express.Router(); +const { isAdminLogedIn } = require('../middlewares/authMiddleware'); +const { getUserList, blockUser, unblockUser } = require('../controller/adminUser') + +router.get('/', isAdminLogedIn, getUserList) +router.put('/block/:id', isAdminLogedIn, blockUser) +router.put('/unblock/:id', isAdminLogedIn, unblockUser) +module.exports = router; \ No newline at end of file diff --git a/server/routes/communityRoute.js b/server/routes/communityRoute.js index 7c742c9..374775a 100644 --- a/server/routes/communityRoute.js +++ b/server/routes/communityRoute.js @@ -8,4 +8,8 @@ router.post('/', isLogedIn, createCommunity) router.post('/join', isLogedIn, joinCommunity) router.post('/accept-join', isLogedIn, acceptJoin) router.get('/my-communities', isLogedIn, getmyCommunities) + + +//discussion + module.exports = router; \ No newline at end of file diff --git a/server/routes/indexRoute.js b/server/routes/indexRoute.js new file mode 100644 index 0000000..df7a3ce --- /dev/null +++ b/server/routes/indexRoute.js @@ -0,0 +1,31 @@ +const express = require('express'); +const router = express.Router(); +const { signup, verifyMail, verifyOtp, signin } = require('../controller/authController'); +const profileRoute = require('./profileRoute') +const userRightsRoute = require('./userRightsRoute') +const userMyBodyRoute = require('./userMyBodyRoute') +const userMyMindRoute = require('./userMyMindRoute') +const communityRoute = require('./communityRoute') +const userRoute = require('./userRoute') + +//authentication +router.post('/signup', signup) +router.post('/verify-mail', verifyMail) +router.post('/verify-otp', verifyOtp) +router.post('/signin', signin) + +router.use('/profile', profileRoute) +router.use('/rights', userRightsRoute) +router.use('/my-body', userMyBodyRoute) +router.use('/my-mind', userMyMindRoute) +router.use('/community', communityRoute) +router.use('/users', userRoute) + +router.post('/chat', (req, res) => { + res.status(200).json({ + success: true, + message: "this is the response for " + req.body.query.slice(0, 10) + }) +}) + +module.exports = router; \ No newline at end of file diff --git a/server/routes/userMyMindRoute.js b/server/routes/userMyMindRoute.js new file mode 100644 index 0000000..5c118c3 --- /dev/null +++ b/server/routes/userMyMindRoute.js @@ -0,0 +1,7 @@ +const express = require('express'); +const { isLogedIn } = require('../middlewares/authMiddleware'); +const { getContents } = require('../controller/myMind') +const router = express.Router(); + +router.get('/', isLogedIn, getContents) +module.exports = router; \ No newline at end of file diff --git a/server/routes/userRoute.js b/server/routes/userRoute.js index 87c5aed..5d0737d 100644 --- a/server/routes/userRoute.js +++ b/server/routes/userRoute.js @@ -1,26 +1,10 @@ const express = require('express'); +const { isLogedIn } = require('../middlewares/authMiddleware'); const router = express.Router(); -const { signup, verifyMail, verifyOtp, signin } = require('../controller/authController'); -const profileRoute = require('./profileRoute') -const userRightsRoute = require('./userRightsRoute') -const userMyBodyRoute = require('./userMyBodyRoute') -const communityRoute = require('./communityRoute') -//authentication -router.post('/signup', signup) -router.post('/verify-mail', verifyMail) -router.post('/verify-otp', verifyOtp) -router.post('/signin', signin) +const { getUsers, getUserDetails, reportUser } = require('../controller/userController') -router.use('/profile', profileRoute) -router.use('/rights', userRightsRoute) -router.use('/my-body', userMyBodyRoute) -router.use('/community', communityRoute) - -router.post('/chat', (req, res) => { - res.status(200).json({ - success: true, - message: "this is the response for " + req.body.query.slice(0, 10) - }) -}) +router.get('/', isLogedIn, getUsers) +router.get('/:id', isLogedIn, getUserDetails) +router.post('/report', isLogedIn, reportUser) module.exports = router; \ No newline at end of file From f7a2d05aaa9c6bb74f18c98a76b44001f9b62845 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 22:57:34 +0530 Subject: [PATCH 23/63] feat: added discussion model --- server/models/discussionModel.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 server/models/discussionModel.js diff --git a/server/models/discussionModel.js b/server/models/discussionModel.js new file mode 100644 index 0000000..c09e4ee --- /dev/null +++ b/server/models/discussionModel.js @@ -0,0 +1,32 @@ +const mongoose = require("mongoose"); + +const discussionSchema = new mongoose.Schema({ + community_id: { + type: mongoose.Types.ObjectId, + ref: 'Community', + required: true + }, + user_id: { + type: mongoose.Types.ObjectId, + ref: 'User', + required: true + }, + content: { + type: 'string', + required: true + }, + likes: [ + { + type: mongoose.Types.ObjectId, + ref: 'User', + default: [] + } + ], + caption: { type: 'string' }, + content_type: { type: 'string', enum: ['MEDIA', 'TEXT'] }, + file_type: { type: 'string', enum: ['IMAGE', 'VIDEO'] }, + is_delete: { type: Boolean, default: false } + +}, { timestamps: true }); + +module.exports = mongoose.model("Discussion", discussionSchema); \ No newline at end of file From 247321b0960daa93ca732a979a0bf589a8d1988b Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sat, 9 Mar 2024 23:52:47 +0530 Subject: [PATCH 24/63] feat: create discussion api added --- server/controller/discussion.js | 692 ++++++++++++++++++++++++++++++++ server/routes/communityRoute.js | 9 +- 2 files changed, 700 insertions(+), 1 deletion(-) create mode 100644 server/controller/discussion.js diff --git a/server/controller/discussion.js b/server/controller/discussion.js new file mode 100644 index 0000000..aed4031 --- /dev/null +++ b/server/controller/discussion.js @@ -0,0 +1,692 @@ +const Discussion = require("../models/discussionModel") + +/** + * @desc function creating discussion + * @route POST /api/community/discussions + * @access private + */ +const createDiscussion = async (req, res, next) => { + const { content, community_id, user_id } = req.body; + if (!content || !community_id || !user_id) { + res.status(400); + return next(new Error('Invalid details')); + } + const newDiscussion = await new Discussion(req.body).save() + if (newDiscussion) { + const discussion = await Discussion.aggregate([ + { + $match: { + _id: newDiscussion._id + } + }, + { + $lookup: { + from: "profiles", + localField: 'user_id', + foreignField: 'user_id', + as: 'userProfile', + pipeline: [ + { + $lookup: { + from: "users", + localField: 'user_id', + foreignField: '_id', + as: 'user', + } + }, + { + $unwind: { + path: '$user' + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + user_id: 1, + email: '$user.email' + } + } + ] + } + }, + { + $unwind: { + path: '$userProfile' + } + } + ]) + if (discussion) { + res.status(200).json({ + status: 'created', + message: 'new discussion added', + discussion: discussion[0] + }) + } + } + +} + +// /** +// * @desc function discussions of a community +// * @route GET /api/community/discussions/:id +// * @access private +// */ +// export const getDiscussions: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400); +// return next(new Error('community not found')) +// } + +// const page = (req.query.page && typeof (req.query.page) === "string") ? req.query.page : null +// const pageSize = 3; +// const query = page ? { +// createdAt: { $lt: new Date(page) } +// } : {} + +// const discussions = await Discussion.aggregate([ +// { +// $match: { +// community_id: new ObjectId(id), +// is_delete: false +// } +// }, +// { +// $sort: { +// createdAt: -1 +// } +// }, +// { +// $match: query +// }, +// { +// $limit: pageSize +// }, +// { +// $lookup: { +// from: "comments", +// localField: '_id', +// foreignField: 'post_id', +// as: "comments", +// } +// }, +// { +// $lookup: { +// from: "userprofiles", +// localField: 'user_id', +// foreignField: 'user_id', +// as: 'userProfile', +// pipeline: [ +// { +// $lookup: { +// from: "users", +// localField: 'user_id', +// foreignField: '_id', +// as: 'user', +// } +// }, +// { +// $unwind: { +// path: '$user' +// } +// }, +// { +// $project: { +// username: 1, +// profile_img: 1, +// fullname: 1, +// user_id: 1, +// verified: 1, +// email: '$user.email' +// } +// } +// ] +// } +// }, +// { +// $unwind: { +// path: '$userProfile' +// } +// }, +// { +// $project: { +// _id: 1, +// content: 1, +// user_id: 1, +// likes: 1, +// community_id: 1, +// content_type: 1, +// file_type: 1, +// caption: 1, +// is_delete: 1, +// createdAt: 1, +// userProfile: 1, +// comments: { $size: "$comments" }, +// } +// } +// ]) + + +// if (discussions) { +// res.status(200).json({ +// status: 'ok', +// message: 'discussion fetched', +// discussions +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc requst for recent discussions of a community +// * @route GET /api/community/discussions/recent +// * @access private +// */ +// export const getRecentDiscussion: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const page = (req.query.page && typeof (req.query.page) === "string") ? req.query.page : null +// const pageSize = 3; +// const query = page ? { +// createdAt: { $lt: new Date(page) } +// } : {} + +// const community = await Members.find({ user_id: req.user?._id, status: 'active' }) +// const communityId = community.map((item) => item.community_id); + +// const discussions = await Discussion.aggregate([ +// { +// $match: { +// community_id: { $in: communityId }, +// is_delete: false +// } +// }, +// { +// $sort: { +// createdAt: -1 +// } +// }, +// { +// $match: query +// }, +// { +// $limit: pageSize +// }, +// { +// $lookup: { +// from: "comments", +// localField: '_id', +// foreignField: 'post_id', +// as: "comments", +// } +// }, +// { +// $lookup: { +// from: "userprofiles", +// localField: 'user_id', +// foreignField: 'user_id', +// as: 'userProfile', +// pipeline: [ +// { +// $lookup: { +// from: "users", +// localField: 'user_id', +// foreignField: '_id', +// as: 'user', +// } +// }, +// { +// $unwind: { +// path: '$user' +// } +// }, +// { +// $project: { +// username: 1, +// profile_img: 1, +// fullname: 1, +// user_id: 1, +// verified: 1, +// email: '$user.email' +// } +// } +// ] +// } +// }, +// { +// $unwind: { +// path: '$userProfile' +// } +// }, +// { +// $project: { +// _id: 1, +// content: 1, +// user_id: 1, +// likes: 1, +// community_id: 1, +// content_type: 1, +// file_type: 1, +// caption: 1, +// is_delete: 1, +// createdAt: 1, +// userProfile: 1, +// comments: { $size: "$comments" }, +// } +// } +// ]) + + +// if (discussions) { +// res.status(200).json({ +// status: 'ok', +// message: 'discussion fetched', +// discussions +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc function for deleting a discussions +// * @route DELETE /api/community/discussions/:id +// * @access private +// */ +// export const deleteDiscussion: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400); +// return next(new Error('discussion not found')) +// } +// const deletedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $set: { is_delete: true } }, { new: true }) +// if (deletedDiscussion) { +// res.status(200).json({ +// status: 'ok', +// message: 'discussion deleted', +// deletedDiscussion +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc function for like a discussions +// * @route DELETE /api/community/discussions/like/:id +// * @access private +// */ +// export const likeDiscussion: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400); +// return next(new Error('discussion not found')) +// } +// const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $addToSet: { likes: req.user?._id } }, { new: true }) +// if (likedDiscussion) { +// res.status(200).json({ +// status: 'ok', +// message: 'discussion liked', +// likedDiscussion +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc function for dislike a discussions +// * @route DELETE /api/community/discussions/dislike/:id +// * @access private +// */ +// export const dislikeDiscussion: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400); +// return next(new Error('discussion not found')) +// } +// const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) +// if (likedDiscussion) { +// res.status(200).json({ +// status: 'ok', +// message: 'discussion disliked', +// likedDiscussion +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc rquest for add commment on a discussions +// * @route POST /api/community/discussions/comment +// * @access private +// */ +// export const addComment: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { discussion_id } = req.body; +// if (!discussion_id) { +// res.status(400) +// return next(new Error("Invalid discussion")); +// } +// const newComment = await new Comment({ +// user_id: req.user?._id, +// post_id: req.body.discussion_id, +// content: req.body.content +// }) +// if (req.body.reply) { +// newComment.reply = req.body.reply +// } +// const comment = await newComment.save() + +// if (comment) { +// const resComment = await Comment.aggregate([ +// { +// $match: { +// _id: comment._id +// } +// }, +// { +// $lookup: { +// from: 'userprofiles', +// localField: 'user_id', +// foreignField: 'user_id', +// as: 'user_details', +// pipeline: [ +// { +// $lookup: { +// from: 'users', +// localField: 'user_id', +// foreignField: '_id', +// as: "email", +// pipeline: [ +// { +// $project: { +// _id: 0, +// email: 1 +// } +// } +// ] + +// } +// }, +// { +// $unwind: { +// path: "$email" +// } +// }, +// { +// $project: { +// username: 1, +// profile_img: 1, +// email: '$email.email' +// } +// }, + +// ] +// } +// }, { +// $unwind: { +// path: '$user_details' +// } +// }, + +// ]) +// res.status(200).json({ +// status: 'ok', +// message: 'new Comment added', +// comment: resComment[0] +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc rquest for fetching comments of a discussion +// * @route GET /api/community/discussions/comment/:id +// * @access private +// */ +// export const getComments: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400) +// return next(new Error("Invalid discussion")); +// } + + +// const comments = await Comment.aggregate([ +// { +// $match: { +// post_id: new ObjectId(id) +// } +// }, +// { +// $lookup: { +// from: 'userprofiles', +// localField: 'user_id', +// foreignField: 'user_id', +// as: 'user_details', +// pipeline: [ +// { +// $lookup: { +// from: 'users', +// localField: 'user_id', +// foreignField: '_id', +// as: "email", +// pipeline: [ +// { +// $project: { +// _id: 0, +// email: 1 +// } +// } +// ] + +// } +// }, +// { +// $unwind: { +// path: "$email" +// } +// }, +// { +// $project: { +// username: 1, +// profile_img: 1, +// email: '$email.email' +// } +// }, + +// ] +// } +// }, { +// $unwind: { +// path: '$user_details' +// } +// }, + +// ]) +// if (comments) { +// res.status(200).json({ +// status: 'ok', +// message: 'comments fetched', +// comment: comments +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + +// /** +// * @desc rquest for fetching replyies of comment +// * @route GET /api/community/discussions/comment/reply/:id +// * @access private +// */ +// export const getReplyCommemts: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400) +// return next(new Error("Invalid comment")); +// } + + +// const comments = await Comment.aggregate([ +// { +// $match: { +// reply: new ObjectId(id) +// } +// }, +// { +// $lookup: { +// from: 'userprofiles', +// localField: 'user_id', +// foreignField: 'user_id', +// as: 'user_details', +// pipeline: [ +// { +// $lookup: { +// from: 'users', +// localField: 'user_id', +// foreignField: '_id', +// as: "email", +// pipeline: [ +// { +// $project: { +// _id: 0, +// email: 1 +// } +// } +// ] + +// } +// }, +// { +// $unwind: { +// path: "$email" +// } +// }, +// { +// $project: { +// username: 1, +// profile_img: 1, +// email: '$email.email' +// } +// }, + +// ] +// } +// }, { +// $unwind: { +// path: '$user_details' +// } +// }, + +// ]) +// if (comments) { +// res.status(200).json({ +// status: 'ok', +// message: 'reply comment fetched', +// comment: comments +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + + +// /** +// * @desc rquest for add commment on a discussions +// * @route DELETE /api/community/discussions/comment +// * @access private +// */ +// export const deleteComment: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400) +// return next(new Error("Invalid comment")); +// } +// const deletedComment = await Comment.findOneAndDelete({ _id: id }) +// if (deletedComment) { +// res.status(200).json({ +// status: 'ok', +// message: 'comment deleted', +// deletedComment +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + + +// /** +// * @desc rquest for add like on comment +// * @route PUT /api/community/discussions/comment/like/:id +// * @access private +// */ +// export const likeComment: RequestHandler = asyncHandler( +// async (req: Request, res: Response, next: NextFunction): Promise => { +// const { id } = req.params; +// if (!id) { +// res.status(400) +// return next(new Error("Invalid comment")); +// } +// const comment = await Comment.findOneAndUpdate({ _id: id }, { $addToSet: { likes: req.user?._id } }, { new: true }) +// if (comment) { +// res.status(200).json({ +// status: 'ok', +// message: 'comment liked', +// comment +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } +// ) + + +// /** +// * @desc rquest for dislike on comment +// * @route PUT /api/community/discussions/comment/dislike/:id +// * @access private +// */ +// const dislikeComment = async (req, res, next) => { +// const { id } = req.params; +// if (!id) { +// res.status(400) +// return next(new Error("Invalid comment")); +// } +// const comment = await Comment.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) +// if (comment) { +// res.status(200).json({ +// status: 'ok', +// message: 'comment disliked', +// comment +// }) +// } else { +// next(new Error('Internal server error')) +// } +// } + + +module.exports = { + createDiscussion +} \ No newline at end of file diff --git a/server/routes/communityRoute.js b/server/routes/communityRoute.js index 374775a..1ceeb2c 100644 --- a/server/routes/communityRoute.js +++ b/server/routes/communityRoute.js @@ -2,6 +2,8 @@ const express = require('express'); const { isLogedIn } = require('../middlewares/authMiddleware'); const router = express.Router(); const { createCommunity, getSuggestions, joinCommunity, acceptJoin, getmyCommunities } = require('../controller/community') +const { createDiscussion } = require('../controller/discussion') +// const { getDiscussions, createDiscussion, getRecentDiscussion, deleteDiscussion, likeDiscussion, dislikeDiscussion } = require('../controller/discussion') router.get('/get-suggestions', isLogedIn, getSuggestions) router.post('/', isLogedIn, createCommunity) @@ -11,5 +13,10 @@ router.get('/my-communities', isLogedIn, getmyCommunities) //discussion - +// router.get('/discussions/recent', isLogedIn, getRecentDiscussion) +// router.get('/discussions/:id', isLogedIn, getDiscussions) +router.post('/discussions', isLogedIn, createDiscussion) +// router.delete('/discussions/:id', isLogedIn, deleteDiscussion) +// router.put('/discussions/like/:id', isLogedIn, likeDiscussion) +// router.put('/discussions/dislike/:id', isLogedIn, dislikeDiscussion) module.exports = router; \ No newline at end of file From 736cf620d8c0806b9c369b7dd92b1585e5eb2f5c Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sun, 10 Mar 2024 00:01:56 +0530 Subject: [PATCH 25/63] feat: comment schema added --- server/controller/discussion.js | 212 ++++++++++++++++---------------- server/models/commentModel.js | 0 2 files changed, 103 insertions(+), 109 deletions(-) create mode 100644 server/models/commentModel.js diff --git a/server/controller/discussion.js b/server/controller/discussion.js index aed4031..a7fc8d0 100644 --- a/server/controller/discussion.js +++ b/server/controller/discussion.js @@ -68,119 +68,113 @@ const createDiscussion = async (req, res, next) => { } -// /** -// * @desc function discussions of a community -// * @route GET /api/community/discussions/:id -// * @access private -// */ -// export const getDiscussions: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400); -// return next(new Error('community not found')) -// } +/** + * @desc function discussions of a community + * @route GET /api/community/discussions/:id + * @access private + */ -// const page = (req.query.page && typeof (req.query.page) === "string") ? req.query.page : null -// const pageSize = 3; -// const query = page ? { -// createdAt: { $lt: new Date(page) } -// } : {} +const getDiscussions = async (req, res, next) => { + const { id } = req.params; + if (!id) { + res.status(400); + return next(new Error('community not found')) + } -// const discussions = await Discussion.aggregate([ -// { -// $match: { -// community_id: new ObjectId(id), -// is_delete: false -// } -// }, -// { -// $sort: { -// createdAt: -1 -// } -// }, -// { -// $match: query -// }, -// { -// $limit: pageSize -// }, -// { -// $lookup: { -// from: "comments", -// localField: '_id', -// foreignField: 'post_id', -// as: "comments", -// } -// }, -// { -// $lookup: { -// from: "userprofiles", -// localField: 'user_id', -// foreignField: 'user_id', -// as: 'userProfile', -// pipeline: [ -// { -// $lookup: { -// from: "users", -// localField: 'user_id', -// foreignField: '_id', -// as: 'user', -// } -// }, -// { -// $unwind: { -// path: '$user' -// } -// }, -// { -// $project: { -// username: 1, -// profile_img: 1, -// fullname: 1, -// user_id: 1, -// verified: 1, -// email: '$user.email' -// } -// } -// ] -// } -// }, -// { -// $unwind: { -// path: '$userProfile' -// } -// }, -// { -// $project: { -// _id: 1, -// content: 1, -// user_id: 1, -// likes: 1, -// community_id: 1, -// content_type: 1, -// file_type: 1, -// caption: 1, -// is_delete: 1, -// createdAt: 1, -// userProfile: 1, -// comments: { $size: "$comments" }, -// } -// } -// ]) + const discussions = await Discussion.aggregate([ + { + $match: { + community_id: new ObjectId(id), + is_delete: false + } + }, + { + $sort: { + createdAt: -1 + } + }, + { + skip: (page - 1) * 10 + }, + { + $limit: 10 + }, + { + $lookup: { + from: "comments", + localField: '_id', + foreignField: 'post_id', + as: "comments", + } + }, + { + $lookup: { + from: "userprofiles", + localField: 'user_id', + foreignField: 'user_id', + as: 'userProfile', + pipeline: [ + { + $lookup: { + from: "users", + localField: 'user_id', + foreignField: '_id', + as: 'user', + } + }, + { + $unwind: { + path: '$user' + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + user_id: 1, + verified: 1, + email: '$user.email' + } + } + ] + } + }, + { + $unwind: { + path: '$userProfile' + } + }, + { + $project: { + _id: 1, + content: 1, + user_id: 1, + likes: 1, + community_id: 1, + content_type: 1, + file_type: 1, + caption: 1, + is_delete: 1, + createdAt: 1, + userProfile: 1, + comments: { $size: "$comments" }, + } + } + ]) -// if (discussions) { -// res.status(200).json({ -// status: 'ok', -// message: 'discussion fetched', -// discussions -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) + if (discussions) { + res.status(200).json({ + status: 'ok', + message: 'discussion fetched', + discussions + }) + } else { + next(new Error('Internal server error')) + } +} +) // /** // * @desc requst for recent discussions of a community diff --git a/server/models/commentModel.js b/server/models/commentModel.js new file mode 100644 index 0000000..e69de29 From ad3c48199a4b98806236ece1eb8bc58d23bbb857 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:11:50 +0530 Subject: [PATCH 26/63] fix: admin right management services added --- client/src/Services/rightServices.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/src/Services/rightServices.js b/client/src/Services/rightServices.js index ef248e2..4056d45 100644 --- a/client/src/Services/rightServices.js +++ b/client/src/Services/rightServices.js @@ -10,8 +10,6 @@ export const createRight = async (rightDetails) => { } export const editRight = async (rightDetails, rightId) => { try { - console.log("details", rightDetails) - console.log("right id", rightId) const response = await thaliaAPI.put(`/admin/rights/${rightId}`, rightDetails, { withCredentials: true }); return response.data; } catch (error) { From 5ce3e6b60b5a68e6d95a52b7aa464f4e4a6440b9 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:16:01 +0530 Subject: [PATCH 27/63] feat: admin body topic creation component --- client/src/components/AddBody/AddBody.jsx | 32 ++++++++++++++++++----- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/client/src/components/AddBody/AddBody.jsx b/client/src/components/AddBody/AddBody.jsx index 2a382e9..bd9c9f6 100644 --- a/client/src/components/AddBody/AddBody.jsx +++ b/client/src/components/AddBody/AddBody.jsx @@ -1,10 +1,13 @@ import { useState } from "react"; import { Modal } from "flowbite-react"; +import { addTopic } from "../../Services/bodyServices"; +import { toast } from "react-toastify"; +// eslint-disable-next-line react/prop-types function AddBody({ openModal, setOpenModal }) { const [formData, setFormData] = useState({ - body_name: "", - body_desc: "", + name: "", + content: "", }); const handleChange = (e) => { const { name, value } = e.target; @@ -13,6 +16,18 @@ function AddBody({ openModal, setOpenModal }) { [name]: value, }); }; + const handleAdd = () => { + const addNew = async () => { + const response = await addTopic(formData); + if (response.success === true) { + formData.name = ""; + formData.content = ""; + setOpenModal(false); + toast.success(response.message); + } + }; + addNew(); + }; return ( <> setOpenModal(false)}> @@ -26,9 +41,9 @@ function AddBody({ openModal, setOpenModal }) {
@@ -36,8 +51,8 @@ function AddBody({ openModal, setOpenModal }) { - From f7dcea18b47fb8dbb0a8beba0388252e23481697 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:17:37 +0530 Subject: [PATCH 28/63] feat: admin body topic edit api integration --- client/src/components/EditBody/EditBody.jsx | 45 ++++++++++++++------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/client/src/components/EditBody/EditBody.jsx b/client/src/components/EditBody/EditBody.jsx index 37a2115..f21d876 100644 --- a/client/src/components/EditBody/EditBody.jsx +++ b/client/src/components/EditBody/EditBody.jsx @@ -1,19 +1,22 @@ -import { useState, useEffect } from "react"; import { Modal } from "flowbite-react"; +import { useState, useEffect } from "react"; +import { toast } from "react-toastify"; +import { editBody } from "../../Services/bodyServices"; -function EditBody({ bodyDetails, openModal, setOpenModal }) { +// eslint-disable-next-line react/prop-types +function EditBody({ setOpenModal, openModal, bodyDetails }) { const [formData, setFormData] = useState({ - body_name: "", - body_desc: "", + name: "", + content: "", }); useEffect(() => { if (bodyDetails) { - // eslint-disable-next-line react/prop-types - formData.body_name = bodyDetails?.name; - // eslint-disable-next-line react/prop-types - formData.body_desc = bodyDetails?.description; + setFormData({ + name: bodyDetails?.name || "", + content: bodyDetails?.content || "", + }); } - }, [formData, bodyDetails]); + }, [bodyDetails]); const handleChange = (e) => { const { name, value } = e.target; setFormData({ @@ -21,6 +24,17 @@ function EditBody({ bodyDetails, openModal, setOpenModal }) { [name]: value, }); }; + + const handleEdit = async () => { + const response = await editBody(formData, bodyDetails?._id); + if (response.success === true) { + toast.success(response.message); + formData.name = ""; + formData.content = ""; + setOpenModal(false); + } + }; + return ( <> setOpenModal(false)}> @@ -34,9 +48,9 @@ function EditBody({ bodyDetails, openModal, setOpenModal }) { @@ -44,15 +58,18 @@ function EditBody({ bodyDetails, openModal, setOpenModal }) { - From 5d14df13b710a41c37f37cc472a98f66148811f1 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:19:26 +0530 Subject: [PATCH 29/63] feat: admin user managment updation --- .../pages/AdminPages/Managment/Managment.jsx | 25 +------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/client/src/pages/AdminPages/Managment/Managment.jsx b/client/src/pages/AdminPages/Managment/Managment.jsx index 132c02b..c43ecd8 100644 --- a/client/src/pages/AdminPages/Managment/Managment.jsx +++ b/client/src/pages/AdminPages/Managment/Managment.jsx @@ -5,7 +5,6 @@ function Managment() { const [openModal, setOpenModal] = useState(false); const [reportObject, setReportObject] = useState(); const handleModal = () => { - console.log("Handle Modal Called"); setOpenModal(true); }; return ( @@ -19,7 +18,6 @@ function Managment() {

User Managment

-
@@ -41,28 +39,7 @@ function Managment() { - - - - - - - - - + - - - - - - - - + {bodyDeatails.map((data, index) => { + return ( + <> + + + + + + + + + + ); + })}
- Amarnath as - SilverLaptop - - - -
From 21094c0adfc706c082dc64c908b4548ed6b1eb5d Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:21:15 +0530 Subject: [PATCH 30/63] feat: admin body topic management --- client/src/pages/AdminPages/MyBody/MyBody.jsx | 106 +++++++++++++----- 1 file changed, 78 insertions(+), 28 deletions(-) diff --git a/client/src/pages/AdminPages/MyBody/MyBody.jsx b/client/src/pages/AdminPages/MyBody/MyBody.jsx index 02a0d85..f870ed8 100644 --- a/client/src/pages/AdminPages/MyBody/MyBody.jsx +++ b/client/src/pages/AdminPages/MyBody/MyBody.jsx @@ -1,20 +1,59 @@ -import { useState } from "react"; -import EditRight from "../../../components/EditRight/EditRight"; +import { useEffect, useState } from "react"; +import EditBody from "../../../components/EditBody/EditBody"; import AddBody from "../../../components/AddBody/AddBody"; +import { getTopics } from "../../../Services/bodyServices"; +import { deleteBody } from "../../../Services/bodyServices"; +import timeFormat from "../../../utils/timeFormat"; +import { toast } from "react-toastify"; function MyBody() { const [openModal, setOpenModal] = useState(false); - // eslint-disable-next-line no-unused-vars - const [rightDetails, setRightDetails] = useState(); + const [bodyDeatails, setBodyDetails] = useState([]); + + const [editBody, setEditBody] = useState(); + const [editModal, setEditModal] = useState(false); + const handleModal = () => { setOpenModal(true); }; + const handleEditModal = (bodyId) => { + setEditModal(true); + const bodyToEdit = bodyDeatails.find((body) => { + return body?._id === bodyId; + }); + setEditBody(bodyToEdit); + }; + useEffect(() => { + const getData = async () => { + const response = await getTopics(); + if (response.success === true) { + setBodyDetails(response.contents); + } + }; + getData(); + }, [ + openModal, + setOpenModal, + setBodyDetails, + setEditModal, + editModal, + setEditBody, + ]); + const handleDelete = async (bodyId) => { + const response = await deleteBody(bodyId); + if (response.success === true) { + setBodyDetails((prevDetails) => + prevDetails.filter((body) => body?._id !== bodyId) + ); + toast.success(response.message); + } + }; return ( <> -
@@ -55,26 +94,37 @@ function MyBody() {
- 1 - Dealing with Period Cramps18-03-2003 - - -
+ {index + 1} + {data?.name} + {timeFormat(data.createdAt)} + + + +
From c29073b699dfeedbc7967344d7fd47c8b442be06 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:25:01 +0530 Subject: [PATCH 31/63] feat: admin rights management code updated --- client/src/pages/AdminPages/Rights/Rights.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/pages/AdminPages/Rights/Rights.jsx b/client/src/pages/AdminPages/Rights/Rights.jsx index 64130f4..8519aca 100644 --- a/client/src/pages/AdminPages/Rights/Rights.jsx +++ b/client/src/pages/AdminPages/Rights/Rights.jsx @@ -24,7 +24,6 @@ function Rights() { setEditRight(rightToEdit); }; useEffect(() => { - console.log("Runnning.."); const getRights = async () => { const response = await getRight(); setRightDetails(response.rights); From b5e784fac8d843e116221093d45b807fc3aa6629 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:26:24 +0530 Subject: [PATCH 32/63] feat: admin body management service integration --- client/src/Services/bodyServices.js | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 client/src/Services/bodyServices.js diff --git a/client/src/Services/bodyServices.js b/client/src/Services/bodyServices.js new file mode 100644 index 0000000..950d103 --- /dev/null +++ b/client/src/Services/bodyServices.js @@ -0,0 +1,38 @@ +import thaliaAPI from "../API/thaliaAPI"; + +export const getTopics = async () => { + try { + const response = await thaliaAPI.get("/admin/my-body", { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + +export const addTopic = async (formData) => { + try { + const response = await thaliaAPI.post("/admin/my-body", formData, { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + +export const deleteBody = async (bodyId) => { + try { + const response = await thaliaAPI.delete(`/admin/my-body/${bodyId}`, { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + +export const editBody = async (formData, bodyId) => { + try { + const response = await thaliaAPI.put(`/admin/my-body/${bodyId}`, formData); + return response.data; + } catch (error) { + console.log("error=>", error) + return error; + } +} \ No newline at end of file From 1b591dbc7dd88d5a9ee48c688f48d4bfbb8aa421 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 00:27:17 +0530 Subject: [PATCH 33/63] admin: admin user managment services integration --- client/src/Services/userService.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 client/src/Services/userService.js diff --git a/client/src/Services/userService.js b/client/src/Services/userService.js new file mode 100644 index 0000000..e69de29 From 5006fdda4593fe11d01b0094c324d7cefc7d10ae Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sun, 10 Mar 2024 01:25:50 +0530 Subject: [PATCH 34/63] feat: added like discussion --- server/controller/discussion.js | 614 +++++++++++++++++--------------- server/routes/communityRoute.js | 10 +- 2 files changed, 325 insertions(+), 299 deletions(-) diff --git a/server/controller/discussion.js b/server/controller/discussion.js index a7fc8d0..d315201 100644 --- a/server/controller/discussion.js +++ b/server/controller/discussion.js @@ -1,4 +1,6 @@ -const Discussion = require("../models/discussionModel") +const Discussion = require("../models/discussionModel"); +const Members = require("../models/membersModel"); +const mongoose = require('mongoose') /** * @desc function creating discussion @@ -6,17 +8,116 @@ const Discussion = require("../models/discussionModel") * @access private */ const createDiscussion = async (req, res, next) => { - const { content, community_id, user_id } = req.body; - if (!content || !community_id || !user_id) { - res.status(400); - return next(new Error('Invalid details')); + try { + const { content, community_id, user_id } = req.body; + if (!content || !community_id || !user_id) { + res.status(400); + throw new Error('details missing') + } + const newDiscussion = await new Discussion(req.body).save() + if (newDiscussion) { + const discussion = await Discussion.aggregate([ + { + $match: { + _id: newDiscussion._id + } + }, + { + $lookup: { + from: "profiles", + localField: 'user_id', + foreignField: 'user_id', + as: 'userProfile', + pipeline: [ + { + $lookup: { + from: "users", + localField: 'user_id', + foreignField: '_id', + as: 'user', + } + }, + { + $unwind: { + path: '$user' + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + user_id: 1, + email: '$user.email' + } + } + ] + } + }, + { + $unwind: { + path: '$userProfile' + } + } + ]) + if (discussion) { + res.status(200).json({ + success: true, + message: 'new discussion added', + discussion: discussion[0] + }) + } + } + } catch (error) { + next(error.message) } - const newDiscussion = await new Discussion(req.body).save() - if (newDiscussion) { - const discussion = await Discussion.aggregate([ + +} + +/** + * @desc function discussions of a community + * @route GET /api/community/discussions/:id + * @access private + */ + +const getDiscussions = async (req, res, next) => { + try { + const { id } = req.params; + const page = req.query.page; + if (!id) { + res.status(400); + throw new Error("community not found") + } + if (!page) { + res.status(400); + throw new Error("page not found") + } + + + const discussions = await Discussion.aggregate([ { $match: { - _id: newDiscussion._id + community_id: new mongoose.Types.ObjectId(id), + is_delete: false + } + }, + { + $sort: { + createdAt: -1 + } + }, + { + $skip: (page - 1) * 10 + }, + { + $limit: 10 + }, + { + $lookup: { + from: "comments", + localField: '_id', + foreignField: 'discussion_id', + as: "comments", } }, { @@ -55,312 +156,233 @@ const createDiscussion = async (req, res, next) => { $unwind: { path: '$userProfile' } + }, + { + $project: { + _id: 1, + content: 1, + user_id: 1, + likes: 1, + community_id: 1, + content_type: 1, + file_type: 1, + caption: 1, + is_delete: 1, + createdAt: 1, + userProfile: 1, + comments: { $size: "$comments" }, + } } ]) - if (discussion) { + + + if (discussions) { res.status(200).json({ - status: 'created', - message: 'new discussion added', - discussion: discussion[0] + success: true, + message: 'discussion fetched', + discussions }) + } else { + throw new Error('Internal server error') } - } + } catch (error) { + next(error.message) + } } /** - * @desc function discussions of a community - * @route GET /api/community/discussions/:id + * @desc requst for recent discussions of a community + * @route GET /api/community/discussions/recent * @access private */ +const getRecentDiscussion = async (req, res, next) => { + try { + const page = req.query.page + if (!page) { + throw new Error('pagination not found') + } -const getDiscussions = async (req, res, next) => { - const { id } = req.params; - if (!id) { - res.status(400); - return next(new Error('community not found')) - } + const community = await Members.find({ user_id: req.user?._id, status: 'active' }) + const communityId = community.map((item) => item.community_id); - const discussions = await Discussion.aggregate([ - { - $match: { - community_id: new ObjectId(id), - is_delete: false - } - }, - { - $sort: { - createdAt: -1 - } - }, - { - skip: (page - 1) * 10 - }, - { - $limit: 10 - }, - { - $lookup: { - from: "comments", - localField: '_id', - foreignField: 'post_id', - as: "comments", - } - }, - { - $lookup: { - from: "userprofiles", - localField: 'user_id', - foreignField: 'user_id', - as: 'userProfile', - pipeline: [ - { - $lookup: { - from: "users", - localField: 'user_id', - foreignField: '_id', - as: 'user', - } - }, - { - $unwind: { - path: '$user' - } - }, - { - $project: { - username: 1, - profile_img: 1, - fullname: 1, - user_id: 1, - verified: 1, - email: '$user.email' + const discussions = await Discussion.aggregate([ + { + $match: { + community_id: { $in: communityId }, + is_delete: false + } + }, + { + $sort: { + createdAt: -1 + } + }, + { + $skip: (page - 1) * 10 + }, + { + $limit: 10 + }, + { + $lookup: { + from: "comments", + localField: '_id', + foreignField: 'discussion_id', + as: "comments", + } + }, + { + $lookup: { + from: "profiles", + localField: 'user_id', + foreignField: 'user_id', + as: 'userProfile', + pipeline: [ + { + $lookup: { + from: "users", + localField: 'user_id', + foreignField: '_id', + as: 'user', + } + }, + { + $unwind: { + path: '$user' + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + user_id: 1, + verified: 1, + email: '$user.email' + } } - } - ] - } - }, - { - $unwind: { - path: '$userProfile' - } - }, - { - $project: { - _id: 1, - content: 1, - user_id: 1, - likes: 1, - community_id: 1, - content_type: 1, - file_type: 1, - caption: 1, - is_delete: 1, - createdAt: 1, - userProfile: 1, - comments: { $size: "$comments" }, + ] + } + }, + { + $unwind: { + path: '$userProfile' + } + }, + { + $project: { + _id: 1, + content: 1, + user_id: 1, + likes: 1, + community_id: 1, + content_type: 1, + file_type: 1, + caption: 1, + is_delete: 1, + createdAt: 1, + userProfile: 1, + comments: { $size: "$comments" }, + } } - } - ]) + ]) - if (discussions) { - res.status(200).json({ - status: 'ok', - message: 'discussion fetched', - discussions - }) - } else { - next(new Error('Internal server error')) + if (discussions) { + res.status(200).json({ + success: true, + message: 'recent discussion fetched', + discussions + }) + } else { + throw new Error('Internal server error') + } + } catch (error) { + next(error.message) } } -) - -// /** -// * @desc requst for recent discussions of a community -// * @route GET /api/community/discussions/recent -// * @access private -// */ -// export const getRecentDiscussion: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const page = (req.query.page && typeof (req.query.page) === "string") ? req.query.page : null -// const pageSize = 3; -// const query = page ? { -// createdAt: { $lt: new Date(page) } -// } : {} -// const community = await Members.find({ user_id: req.user?._id, status: 'active' }) -// const communityId = community.map((item) => item.community_id); - -// const discussions = await Discussion.aggregate([ -// { -// $match: { -// community_id: { $in: communityId }, -// is_delete: false -// } -// }, -// { -// $sort: { -// createdAt: -1 -// } -// }, -// { -// $match: query -// }, -// { -// $limit: pageSize -// }, -// { -// $lookup: { -// from: "comments", -// localField: '_id', -// foreignField: 'post_id', -// as: "comments", -// } -// }, -// { -// $lookup: { -// from: "userprofiles", -// localField: 'user_id', -// foreignField: 'user_id', -// as: 'userProfile', -// pipeline: [ -// { -// $lookup: { -// from: "users", -// localField: 'user_id', -// foreignField: '_id', -// as: 'user', -// } -// }, -// { -// $unwind: { -// path: '$user' -// } -// }, -// { -// $project: { -// username: 1, -// profile_img: 1, -// fullname: 1, -// user_id: 1, -// verified: 1, -// email: '$user.email' -// } -// } -// ] -// } -// }, -// { -// $unwind: { -// path: '$userProfile' -// } -// }, -// { -// $project: { -// _id: 1, -// content: 1, -// user_id: 1, -// likes: 1, -// community_id: 1, -// content_type: 1, -// file_type: 1, -// caption: 1, -// is_delete: 1, -// createdAt: 1, -// userProfile: 1, -// comments: { $size: "$comments" }, -// } -// } -// ]) - - -// if (discussions) { -// res.status(200).json({ -// status: 'ok', -// message: 'discussion fetched', -// discussions -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) - -// /** -// * @desc function for deleting a discussions -// * @route DELETE /api/community/discussions/:id -// * @access private -// */ -// export const deleteDiscussion: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400); -// return next(new Error('discussion not found')) -// } -// const deletedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $set: { is_delete: true } }, { new: true }) -// if (deletedDiscussion) { -// res.status(200).json({ -// status: 'ok', -// message: 'discussion deleted', -// deletedDiscussion -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) +/** + * @desc function for deleting a discussions + * @route DELETE /api/community/discussions/:id + * @access private + */ +const deleteDiscussion = async (req, res, next) => { + try { + const { id } = req.params; + if (!id) { + res.status(400); + throw new Error('discussion not found') + } + const deletedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $set: { is_delete: true } }, { new: true }) + if (deletedDiscussion) { + res.status(200).json({ + success: true, + message: 'discussion deleted', + deletedDiscussion + }) + } else { + throw new Error('internal server error') + } + } catch (error) { + next(error.message) + } +} -// /** -// * @desc function for like a discussions -// * @route DELETE /api/community/discussions/like/:id -// * @access private -// */ -// export const likeDiscussion: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400); -// return next(new Error('discussion not found')) -// } -// const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $addToSet: { likes: req.user?._id } }, { new: true }) -// if (likedDiscussion) { -// res.status(200).json({ -// status: 'ok', -// message: 'discussion liked', -// likedDiscussion -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) +/** + * @desc function for like a discussions + * @route PUT /api/community/discussions/like/:id + * @access private + */ +const likeDiscussion = async (req, res, next) => { + try { + const { id } = req.params; + if (!id) { + res.status(400); + throw new Error('discussion not found') + } + const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $addToSet: { likes: req.user?._id } }, { new: true }) + if (likedDiscussion) { + res.status(200).json({ + success: true, + message: 'discussion liked', + likedDiscussion + }) + } else { + throw new Error('internal server error') + } + } catch (error) { + next(error.message) + } +} -// /** -// * @desc function for dislike a discussions -// * @route DELETE /api/community/discussions/dislike/:id -// * @access private -// */ -// export const dislikeDiscussion: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400); -// return next(new Error('discussion not found')) -// } -// const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) -// if (likedDiscussion) { -// res.status(200).json({ -// status: 'ok', -// message: 'discussion disliked', -// likedDiscussion -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) +/** + * @desc function for dislike a discussions + * @route PUT /api/community/discussions/dislike/:id + * @access private + */ +const dislikeDiscussion = async (req, res, next) => { + try { + const { id } = req.params; + if (!id) { + res.status(400); + throw new Error('discussion not found') + } + const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) + if (likedDiscussion) { + res.status(200).json({ + success: true, + message: 'discussion disliked', + likedDiscussion + }) + } else { + throw new Error('internal server error') + } + } catch (error) { + next(error.message) + } +} // /** // * @desc rquest for add commment on a discussions @@ -682,5 +704,9 @@ const getDiscussions = async (req, res, next) => { module.exports = { - createDiscussion + createDiscussion, + getDiscussions, + getRecentDiscussion, + deleteDiscussion, + likeDiscussion } \ No newline at end of file diff --git a/server/routes/communityRoute.js b/server/routes/communityRoute.js index 1ceeb2c..e0a5058 100644 --- a/server/routes/communityRoute.js +++ b/server/routes/communityRoute.js @@ -2,7 +2,7 @@ const express = require('express'); const { isLogedIn } = require('../middlewares/authMiddleware'); const router = express.Router(); const { createCommunity, getSuggestions, joinCommunity, acceptJoin, getmyCommunities } = require('../controller/community') -const { createDiscussion } = require('../controller/discussion') +const { createDiscussion, getDiscussions, getRecentDiscussion, deleteDiscussion, likeDiscussion } = require('../controller/discussion') // const { getDiscussions, createDiscussion, getRecentDiscussion, deleteDiscussion, likeDiscussion, dislikeDiscussion } = require('../controller/discussion') router.get('/get-suggestions', isLogedIn, getSuggestions) @@ -13,10 +13,10 @@ router.get('/my-communities', isLogedIn, getmyCommunities) //discussion -// router.get('/discussions/recent', isLogedIn, getRecentDiscussion) -// router.get('/discussions/:id', isLogedIn, getDiscussions) +router.get('/discussions/recent', isLogedIn, getRecentDiscussion) +router.get('/discussions/:id', isLogedIn, getDiscussions) router.post('/discussions', isLogedIn, createDiscussion) -// router.delete('/discussions/:id', isLogedIn, deleteDiscussion) -// router.put('/discussions/like/:id', isLogedIn, likeDiscussion) +router.delete('/discussions/:id', isLogedIn, deleteDiscussion) +router.put('/discussions/like/:id', isLogedIn, likeDiscussion) // router.put('/discussions/dislike/:id', isLogedIn, dislikeDiscussion) module.exports = router; \ No newline at end of file From 5607de8a078e47fede8c16428785b7600de7f5b8 Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sun, 10 Mar 2024 02:10:21 +0530 Subject: [PATCH 35/63] fix: updated the cors in AI server --- ai_server/ai_server/settings.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ai_server/ai_server/settings.py b/ai_server/ai_server/settings.py index 8b04ffe..33fba6e 100644 --- a/ai_server/ai_server/settings.py +++ b/ai_server/ai_server/settings.py @@ -127,4 +127,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" -CORS_ORIGIN_ALLOW_ALL = True \ No newline at end of file +CORS_ALLOWED_ORIGINS = [ + "http://localhost:4000", + "https://thalia.vercel.app", +] \ No newline at end of file From eb4d2f2ec6fe5a3ff213fe96c6b43b51061b7835 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sun, 10 Mar 2024 02:17:46 +0530 Subject: [PATCH 36/63] feat: added create comment and get comment api --- server/controller/discussion.js | 491 ++++++++++++++++---------------- server/models/commentModel.js | 27 ++ server/routes/communityRoute.js | 10 +- 3 files changed, 287 insertions(+), 241 deletions(-) diff --git a/server/controller/discussion.js b/server/controller/discussion.js index d315201..25ec014 100644 --- a/server/controller/discussion.js +++ b/server/controller/discussion.js @@ -1,5 +1,6 @@ const Discussion = require("../models/discussionModel"); const Members = require("../models/membersModel"); +const Comment = require("../models/commentModel"); const mongoose = require('mongoose') /** @@ -369,12 +370,12 @@ const dislikeDiscussion = async (req, res, next) => { res.status(400); throw new Error('discussion not found') } - const likedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) - if (likedDiscussion) { + const dislikedDiscussion = await Discussion.findOneAndUpdate({ _id: id }, { $pull: { likes: req.user?._id } }, { new: true }) + if (dislikedDiscussion) { res.status(200).json({ success: true, message: 'discussion disliked', - likedDiscussion + dislikedDiscussion }) } else { throw new Error('internal server error') @@ -384,247 +385,257 @@ const dislikeDiscussion = async (req, res, next) => { } } -// /** -// * @desc rquest for add commment on a discussions -// * @route POST /api/community/discussions/comment -// * @access private -// */ -// export const addComment: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { discussion_id } = req.body; -// if (!discussion_id) { -// res.status(400) -// return next(new Error("Invalid discussion")); -// } -// const newComment = await new Comment({ -// user_id: req.user?._id, -// post_id: req.body.discussion_id, -// content: req.body.content -// }) -// if (req.body.reply) { -// newComment.reply = req.body.reply -// } -// const comment = await newComment.save() +/** + * @desc rquest for add commment on a discussions + * @route POST /api/community/discussions/comment + * @access private + */ +const addComment = async (req, res, next) => { + try { + const { discussion_id } = req.body; + if (!discussion_id) { + res.status(400) + throw new Error('discussion not found') + } + const newComment = new Comment({ + user_id: req.user?._id, + discussion_id: req.body.discussion_id, + content: req.body.content + }) + if (req.body.reply) { + newComment.reply = req.body.reply + } + const comment = await newComment.save() -// if (comment) { -// const resComment = await Comment.aggregate([ -// { -// $match: { -// _id: comment._id -// } -// }, -// { -// $lookup: { -// from: 'userprofiles', -// localField: 'user_id', -// foreignField: 'user_id', -// as: 'user_details', -// pipeline: [ -// { -// $lookup: { -// from: 'users', -// localField: 'user_id', -// foreignField: '_id', -// as: "email", -// pipeline: [ -// { -// $project: { -// _id: 0, -// email: 1 -// } -// } -// ] - -// } -// }, -// { -// $unwind: { -// path: "$email" -// } -// }, -// { -// $project: { -// username: 1, -// profile_img: 1, -// email: '$email.email' -// } -// }, - -// ] -// } -// }, { -// $unwind: { -// path: '$user_details' -// } -// }, - -// ]) -// res.status(200).json({ -// status: 'ok', -// message: 'new Comment added', -// comment: resComment[0] -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) + if (comment) { + const resComment = await Comment.aggregate([ + { + $match: { + _id: comment._id + } + }, + { + $lookup: { + from: 'profiles', + localField: 'user_id', + foreignField: 'user_id', + as: 'user_details', + pipeline: [ + { + $lookup: { + from: 'users', + localField: 'user_id', + foreignField: '_id', + as: "email", + pipeline: [ + { + $project: { + _id: 0, + email: 1 + } + } + ] -// /** -// * @desc rquest for fetching comments of a discussion -// * @route GET /api/community/discussions/comment/:id -// * @access private -// */ -// export const getComments: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400) -// return next(new Error("Invalid discussion")); -// } + } + }, + { + $unwind: { + path: "$email" + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + email: '$email.email' + } + }, + ] + } + }, { + $unwind: { + path: '$user_details' + } + }, -// const comments = await Comment.aggregate([ -// { -// $match: { -// post_id: new ObjectId(id) -// } -// }, -// { -// $lookup: { -// from: 'userprofiles', -// localField: 'user_id', -// foreignField: 'user_id', -// as: 'user_details', -// pipeline: [ -// { -// $lookup: { -// from: 'users', -// localField: 'user_id', -// foreignField: '_id', -// as: "email", -// pipeline: [ -// { -// $project: { -// _id: 0, -// email: 1 -// } -// } -// ] - -// } -// }, -// { -// $unwind: { -// path: "$email" -// } -// }, -// { -// $project: { -// username: 1, -// profile_img: 1, -// email: '$email.email' -// } -// }, - -// ] -// } -// }, { -// $unwind: { -// path: '$user_details' -// } -// }, - -// ]) -// if (comments) { -// res.status(200).json({ -// status: 'ok', -// message: 'comments fetched', -// comment: comments -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) + ]) + res.status(200).json({ + success: true, + message: 'new Comment added', + comment: resComment[0] + }) + } else { + throw new Error('internal server error') + } + } catch (error) { + next(error.message) + } +} -// /** -// * @desc rquest for fetching replyies of comment -// * @route GET /api/community/discussions/comment/reply/:id -// * @access private -// */ -// export const getReplyCommemts: RequestHandler = asyncHandler( -// async (req: Request, res: Response, next: NextFunction): Promise => { -// const { id } = req.params; -// if (!id) { -// res.status(400) -// return next(new Error("Invalid comment")); -// } +/** + * @desc rquest for fetching comments of a discussion + * @route GET /api/community/discussions/comment/:id + * @access private + */ +const getComments = async (req, res, next) => { + try { + const { id } = req.params; + if (!id) { + res.status(400) + throw new Error('discussion not found') + } -// const comments = await Comment.aggregate([ -// { -// $match: { -// reply: new ObjectId(id) -// } -// }, -// { -// $lookup: { -// from: 'userprofiles', -// localField: 'user_id', -// foreignField: 'user_id', -// as: 'user_details', -// pipeline: [ -// { -// $lookup: { -// from: 'users', -// localField: 'user_id', -// foreignField: '_id', -// as: "email", -// pipeline: [ -// { -// $project: { -// _id: 0, -// email: 1 -// } -// } -// ] - -// } -// }, -// { -// $unwind: { -// path: "$email" -// } -// }, -// { -// $project: { -// username: 1, -// profile_img: 1, -// email: '$email.email' -// } -// }, - -// ] -// } -// }, { -// $unwind: { -// path: '$user_details' -// } -// }, - -// ]) -// if (comments) { -// res.status(200).json({ -// status: 'ok', -// message: 'reply comment fetched', -// comment: comments -// }) -// } else { -// next(new Error('Internal server error')) -// } -// } -// ) + const comments = await Comment.aggregate([ + { + $match: { + discussion_id: new mongoose.Types.ObjectId(id) + } + }, + { + $lookup: { + from: 'profiles', + localField: 'user_id', + foreignField: 'user_id', + as: 'user_details', + pipeline: [ + { + $lookup: { + from: 'users', + localField: 'user_id', + foreignField: '_id', + as: "email", + pipeline: [ + { + $project: { + _id: 0, + email: 1 + } + } + ] + + } + }, + { + $unwind: { + path: "$email" + } + }, + { + $project: { + username: 1, + profile_img: 1, + fullname: 1, + email: '$email.email' + } + }, + + ] + } + }, { + $unwind: { + path: '$user_details' + } + }, + + ]) + if (comments) { + res.status(200).json({ + success: true, + message: 'comments fetched', + comment: comments + }) + } else { + throw new Error('Internal server error') + } + } catch (error) { + next(error.message) + } +} + + +/** + * @desc rquest for fetching replyies of comment + * @route GET /api/community/discussions/comment/reply/:id + * @access private + */ +const getReplyCommemts = async (req, res, next) => { + try { + const { id } = req.params; + if (!id) { + res.status(400) + throw new Error('comment not found') + } + + + const comments = await Comment.aggregate([ + { + $match: { + reply: new mongoose.Types.ObjectId(id) + } + }, + { + $lookup: { + from: 'profiles', + localField: 'user_id', + foreignField: 'user_id', + as: 'user_details', + pipeline: [ + { + $lookup: { + from: 'users', + localField: 'user_id', + foreignField: '_id', + as: "email", + pipeline: [ + { + $project: { + _id: 0, + email: 1 + } + } + ] + + } + }, + { + $unwind: { + path: "$email" + } + }, + { + $project: { + username: 1, + fullname: 1, + profile_img: 1, + email: '$email.email' + } + }, + + ] + } + }, { + $unwind: { + path: '$user_details' + } + }, + + ]) + if (comments) { + res.status(200).json({ + success: true, + message: 'reply comment fetched', + comment: comments + }) + } else { + throw new Error('Internal server error') + } + } catch (error) { + next(error.message) + } +} // /** @@ -708,5 +719,9 @@ module.exports = { getDiscussions, getRecentDiscussion, deleteDiscussion, - likeDiscussion + likeDiscussion, + dislikeDiscussion, + addComment, + getComments, + getReplyCommemts } \ No newline at end of file diff --git a/server/models/commentModel.js b/server/models/commentModel.js index e69de29..aa17d76 100644 --- a/server/models/commentModel.js +++ b/server/models/commentModel.js @@ -0,0 +1,27 @@ +const mongoose = require("mongoose"); + +const commentSchema = new mongoose.Schema({ + discussion_id: { + type: mongoose.Types.ObjectId, + ref: 'Discussion' + }, + user_id: { + type: mongoose.Types.ObjectId, + ref: 'User' + }, + content: { + type: String, + required: true + }, + reply: { + type: mongoose.Types.ObjectId + }, + likes: [ + { + type: mongoose.Types.ObjectId, + ref: 'User' + } + ] +}, { timestamps: true }); + +module.exports = mongoose.model("Comment", commentSchema); \ No newline at end of file diff --git a/server/routes/communityRoute.js b/server/routes/communityRoute.js index e0a5058..790e64a 100644 --- a/server/routes/communityRoute.js +++ b/server/routes/communityRoute.js @@ -2,8 +2,7 @@ const express = require('express'); const { isLogedIn } = require('../middlewares/authMiddleware'); const router = express.Router(); const { createCommunity, getSuggestions, joinCommunity, acceptJoin, getmyCommunities } = require('../controller/community') -const { createDiscussion, getDiscussions, getRecentDiscussion, deleteDiscussion, likeDiscussion } = require('../controller/discussion') -// const { getDiscussions, createDiscussion, getRecentDiscussion, deleteDiscussion, likeDiscussion, dislikeDiscussion } = require('../controller/discussion') +const { createDiscussion, getDiscussions, getRecentDiscussion, deleteDiscussion, likeDiscussion, dislikeDiscussion, addComment, getComments, getReplyCommemts } = require('../controller/discussion') router.get('/get-suggestions', isLogedIn, getSuggestions) router.post('/', isLogedIn, createCommunity) @@ -18,5 +17,10 @@ router.get('/discussions/:id', isLogedIn, getDiscussions) router.post('/discussions', isLogedIn, createDiscussion) router.delete('/discussions/:id', isLogedIn, deleteDiscussion) router.put('/discussions/like/:id', isLogedIn, likeDiscussion) -// router.put('/discussions/dislike/:id', isLogedIn, dislikeDiscussion) +router.put('/discussions/dislike/:id', isLogedIn, dislikeDiscussion) + +router.post('/discussions/comment', isLogedIn, addComment) +router.get('/discussions/comment/:id', isLogedIn, getComments) +router.get('/discussions/comment/reply/:id', isLogedIn, getReplyCommemts) + module.exports = router; \ No newline at end of file From 2138ae137c77d8ffc85f1c082244a3003e54546a Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sun, 10 Mar 2024 02:46:13 +0530 Subject: [PATCH 37/63] feat: added the advanced prompt --- ai_server/chat/prompt.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ai_server/chat/prompt.py b/ai_server/chat/prompt.py index f26e42b..131fd63 100644 --- a/ai_server/chat/prompt.py +++ b/ai_server/chat/prompt.py @@ -1,18 +1,19 @@ PROMPT: str = """ -You are an elder sister for a women. You are an expert at giving guidance and advice to women. -Your only goal is to empower women and stand for their equality. +You are like an elder Didi for all women. Didi means sister in the Hindi language. You are an expert at giving guidance and advice to women. +Your only goal is to empower women and stand for their equality. Your response should be understandable, concise, and in simple English. Your advice should be completely practical and should help their lives directly or indirectly. -Your response should be understandable, concise, and in simple English. +If somebody asks about anything that is not related to women or women's empowerment, please tell them to refer somewhere else politely. +Since you are a sister, never answer current affidavit questions. -sister: Hey, How can I help you? +sister: Hey dear, Do you have anything to share with me? women: My period is late. May I know what the reason is? -sister: If your period is late, there could be various reasons for it, including stress, changes in weight, hormonal imbalances, changes in diet or exercise, certain medications, thyroid issues, polycystic ovary syndrome (PCOS), pregnancy, or other underlying health conditions. It's essential to consult with a healthcare professional, such as a gynaecologist or primary care physician, who can evaluate your individual situation, medical history, and any symptoms you may be experiencing. +sister: Oooh, If your period is late, there could be various reasons for it, including stress, changes in weight, hormonal imbalances, changes in diet or exercise, certain medications, thyroid issues, polycystic ovary syndrome (PCOS), pregnancy, or other underlying health conditions. It's essential to consult with a healthcare professional, such as a gynaecologist or primary care physician, who can evaluate your individual situation, medical history, and any symptoms you may be experiencing. woman: A guy is harassing me. Is there anything I can do about it? -sister: First, stay calm and don't respond to the harasser. Comebacks from stalkers will only increase their level of anger and hatred towards you. \n\n Second, block, mute, and report the harasser. Do this mercilessly and instantly. \n\n Then, let your friends know and also tell them to block, mute, and report the harasser to the local police. Also, call the women's helpline number, 1091. +Sister: Listen to me carefully. First, stay calm and don't respond to the harasser. Comebacks from stalkers will only increase their level of anger and hatred towards you. \n\n Second, block, mute, and report the harasser. Do this mercilessly and instantly. \n\n Then, let your friends know and also tell them to block, mute, and report the harasser to the local police. Also, call the women's helpline number, 1091. Women: Who is the president of the United States of America? -sister: I think this question is not related to women or women's improvements. It will be better if you refer to this question in some other sources 😊. +sister: Hmm, I think this question is not related to women or women's improvements. It will be better if you refer to this question in some other sources 😊. women: {prompt} sister: From c249cd62cf6d11fabbc2b6126f45a7bac45bd093 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 02:46:37 +0530 Subject: [PATCH 38/63] feat: admin user mangement service --- client/src/Services/userService.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/client/src/Services/userService.js b/client/src/Services/userService.js index e69de29..a68d726 100644 --- a/client/src/Services/userService.js +++ b/client/src/Services/userService.js @@ -0,0 +1,29 @@ +import thaliaAPI from "../API/thaliaAPI"; + +export const getUsers = async () => { + try { + const response = await thaliaAPI.get("/admin/users", { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + +export const blockUser = async (userId) => { + try { + const response = await thaliaAPI.put(`/admin/users/block/${userId}`, { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + +export const unBlockUser = async (userId) => { + try { + const response = await thaliaAPI.put(`/admin/users/unblock/${userId}`, { withCredentials: true }); + return response.data; + } catch (error) { + return error; + } +} + From bc80cfbd1692e0cfa80b5da0b3500d5015486d8f Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 02:48:22 +0530 Subject: [PATCH 39/63] feat: admin Add body management --- client/src/components/AddBody/AddBody.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/AddBody/AddBody.jsx b/client/src/components/AddBody/AddBody.jsx index bd9c9f6..760184f 100644 --- a/client/src/components/AddBody/AddBody.jsx +++ b/client/src/components/AddBody/AddBody.jsx @@ -40,7 +40,7 @@ function AddBody({ openModal, setOpenModal }) {

Name of the Topic

- - - From ab589e9cc0fb3865495b79632eaa2fad141ea19f Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 02:58:53 +0530 Subject: [PATCH 47/63] fix: admin my body page update --- client/src/pages/AdminPages/MyBody/MyBody.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/pages/AdminPages/MyBody/MyBody.jsx b/client/src/pages/AdminPages/MyBody/MyBody.jsx index f870ed8..afdd993 100644 --- a/client/src/pages/AdminPages/MyBody/MyBody.jsx +++ b/client/src/pages/AdminPages/MyBody/MyBody.jsx @@ -56,7 +56,7 @@ function MyBody() { bodyDetails={editBody ? editBody : null} /> -
+
{/* Text Components */}
From e435c122277cfa4edf8088a61b31e6c62d52e8e9 Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sun, 10 Mar 2024 03:17:31 +0530 Subject: [PATCH 48/63] style: responsiveness of home page and navbar firxed --- client/src/App.css | 13 +++++++++++++ client/src/components/Nabar/Navbar.jsx | 2 +- .../src/components/ViewMarkModal/ViewMarkModal.jsx | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/client/src/App.css b/client/src/App.css index 25b9795..3aeb655 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -2,6 +2,12 @@ @tailwind components; @tailwind utilities; +* { + padding: 0; + margin: 0; + box-sizing: border-box; +} + *::-webkit-scrollbar-track { background: #291f3a; } @@ -23,3 +29,10 @@ background-color: rgb(74, 29, 86) !important; color: rgb(168, 145, 174) !important; } + +.chat-didi:hover .my-tooltip { + display: inline-block; +} +.my-tooltip { + display: none; +} diff --git a/client/src/components/Nabar/Navbar.jsx b/client/src/components/Nabar/Navbar.jsx index 455a440..fca138d 100644 --- a/client/src/components/Nabar/Navbar.jsx +++ b/client/src/components/Nabar/Navbar.jsx @@ -32,7 +32,7 @@ export default function Navbar() { return ( <> -
+
diff --git a/client/src/components/ViewMarkModal/ViewMarkModal.jsx b/client/src/components/ViewMarkModal/ViewMarkModal.jsx index bf0b38d..ff89638 100644 --- a/client/src/components/ViewMarkModal/ViewMarkModal.jsx +++ b/client/src/components/ViewMarkModal/ViewMarkModal.jsx @@ -12,6 +12,7 @@ export default function ViewMarkModal({ <> { From 633a645c928f0407fa5d1d9401410e19799b7ffe Mon Sep 17 00:00:00 2001 From: Shuhaib T U Date: Sun, 10 Mar 2024 03:18:18 +0530 Subject: [PATCH 49/63] feat: thaliaAI-chatbot ui completed --- client/src/API/aiThaliaAPI.js | 7 + client/src/assets/Chat.svg | 28 +++ client/src/components/BotModal/BotModal.jsx | 164 ++++++++++++++++++ .../src/components/Loader/Loader3/Loader3.css | 30 ++++ .../src/components/Loader/Loader3/Loader3.jsx | 11 ++ client/src/components/UserHome/UserHome.jsx | 58 +++++-- 6 files changed, 280 insertions(+), 18 deletions(-) create mode 100644 client/src/API/aiThaliaAPI.js create mode 100644 client/src/assets/Chat.svg create mode 100644 client/src/components/BotModal/BotModal.jsx create mode 100644 client/src/components/Loader/Loader3/Loader3.css create mode 100644 client/src/components/Loader/Loader3/Loader3.jsx diff --git a/client/src/API/aiThaliaAPI.js b/client/src/API/aiThaliaAPI.js new file mode 100644 index 0000000..b5fa1f5 --- /dev/null +++ b/client/src/API/aiThaliaAPI.js @@ -0,0 +1,7 @@ +import axios from 'axios'; +const baseURL = import.meta.env.VITE_AI_BASE_URL; +const aiThaliaAPI = axios.create({ + baseURL, +}); + +export default aiThaliaAPI; \ No newline at end of file diff --git a/client/src/assets/Chat.svg b/client/src/assets/Chat.svg new file mode 100644 index 0000000..c7a2940 --- /dev/null +++ b/client/src/assets/Chat.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/client/src/components/BotModal/BotModal.jsx b/client/src/components/BotModal/BotModal.jsx new file mode 100644 index 0000000..711f497 --- /dev/null +++ b/client/src/components/BotModal/BotModal.jsx @@ -0,0 +1,164 @@ +import { Modal } from "flowbite-react"; +import SendIcon from "@mui/icons-material/Send"; +import PropTypes from "prop-types"; +import { useEffect, useRef, useState } from "react"; +import aiThaliaAPI from "../../API/aiThaliaAPI"; +import Loader3 from "../../components/Loader/Loader3/Loader3"; + +export default function BotModal({ openModal, setOpenModal }) { + const [query, setQuery] = useState(""); + const [submit, setSubmit] = useState(true); + const scroll = useRef(null); + const qInput = useRef(); + + const [messages, setMessages] = useState([ + { + id: "bot", + message: "", + }, + ]); + + useEffect(() => { + console.log(import.meta.env.VITE_AI_BASE_URL); + if (qInput.current && !submit) { + qInput.current.focus(); + } + }, [submit]); + + useEffect(() => { + scroll.current?.scrollIntoView({ behavior: "smooth" }); + }, [messages, openModal]); + + useEffect(() => { + if (openModal && messages.length < 2) { + setTimeout(() => { + setMessages([ + { + id: "bot", + message: "Hello, Do you have anything to share with me😊", + }, + ]); + setSubmit(false); + }, 1000); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [openModal]); + + useEffect(() => { + (async function () { + if (query && submit) { + try { + const { data } = await aiThaliaAPI.post("/chat", { query: query }); + if (data.success) { + setMessages([ + ...messages, + { + id: "bot", + message: data.message, + }, + ]); + setSubmit(false); + setQuery(""); + } + } catch (err) { + console.log(err); + setQuery(""); + setSubmit(false); + setQuery(""); + } + } + })(); + }, [submit, query, messages]); + + const handlSubmit = (e) => { + e.preventDefault(); + if (query) { + setMessages([ + ...messages, + { + id: "user", + message: query, + }, + ]); + setSubmit(true); + } + }; + + return ( + <> + { + setOpenModal(false); + }} + > + Chat with Didi 🤎 + +
+ {messages.map((e) => { + return ( + <> + {e.id === "bot" ? ( +
+
+ {e.message && ( +
+

{e.message}

+
+ )} +
+
+ ) : ( +
+
+
+

{e.message}

+
+
+
+ )} + + ); + })} + {submit && ( +
+
+
+ +
+
+
+ )} +
+
+ +
+ setQuery(e.target.value)} + /> + +
+ + + ); +} + +BotModal.propTypes = { + openModal: PropTypes.bool.isRequired, + setOpenModal: PropTypes.func.isRequired, +}; diff --git a/client/src/components/Loader/Loader3/Loader3.css b/client/src/components/Loader/Loader3/Loader3.css new file mode 100644 index 0000000..5f0e5cf --- /dev/null +++ b/client/src/components/Loader/Loader3/Loader3.css @@ -0,0 +1,30 @@ +.load { + display: flex; + border-radius: 50%; + flex-direction: row; +} + +.progress { + width: 0.5em; + height: 0.5em; + margin: 0.4em; + scale: 0; + border-radius: 50%; + background: rgb(82, 10, 10); + animation: loading_492 1s ease infinite; + animation-delay: 0.5s; +} + +@keyframes loading_492 { + 50% { + scale: 1; + } +} + +.progress:nth-child(2) { + animation-delay: 1.3s; +} + +.progress:nth-child(3) { + animation-delay: 1.7s; +} \ No newline at end of file diff --git a/client/src/components/Loader/Loader3/Loader3.jsx b/client/src/components/Loader/Loader3/Loader3.jsx new file mode 100644 index 0000000..59bae8e --- /dev/null +++ b/client/src/components/Loader/Loader3/Loader3.jsx @@ -0,0 +1,11 @@ +import "./Loader3.css"; + +export default function Loader3() { + return ( +
+
+
+
+
+ ); +} diff --git a/client/src/components/UserHome/UserHome.jsx b/client/src/components/UserHome/UserHome.jsx index 60f9eb4..a586096 100644 --- a/client/src/components/UserHome/UserHome.jsx +++ b/client/src/components/UserHome/UserHome.jsx @@ -2,28 +2,50 @@ import MybodyCard from "../MyBodyCard/MybodyCard"; import MyLawsCard from "../MyLawsCard/MyLawsCard"; import MyMindCard from "../MyMindCard/MyMindCard"; import CommunityCard from "../CommunityCard/CommunityCard"; +import Chat from "../../assets/Chat.svg"; +import BotModal from "../BotModal/BotModal"; + import { Link } from "react-router-dom"; +import { useState } from "react"; export default function UserHome() { + const [openModal, setOpenModal] = useState(false); + return ( -
-
- - - - - - - - - - + <> + +
+
+ + + + + + + + + + +
+ +
+
+

+ Chat with Didi +

+
+
setOpenModal(true)} + className="w-12 h-12 cursor-pointer rounded-full flex items-center justify-center bg-text" + > + +
+
- -
+ ); } From 23db8a88b9bf45342de5e4b85d18aa954a080e33 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 12:12:48 +0530 Subject: [PATCH 50/63] feat: admin users report checking done --- .../components/CheckReport/CheckReport.jsx | 121 +++++++++++------- 1 file changed, 72 insertions(+), 49 deletions(-) diff --git a/client/src/components/CheckReport/CheckReport.jsx b/client/src/components/CheckReport/CheckReport.jsx index 215891d..f29f1dc 100644 --- a/client/src/components/CheckReport/CheckReport.jsx +++ b/client/src/components/CheckReport/CheckReport.jsx @@ -1,68 +1,91 @@ import { Modal } from "flowbite-react"; import { useState } from "react"; -// eslint-disable-next-line react/prop-types -function CheckReport({ openModal, setOpenModal, reportObject }) { - const [show, setShow] = useState(false); - const handleView = () => { - setShow((state) => !state); +function CheckReport({ openModal, setOpenModal, userReport }) { + const [accordionStates, setAccordionStates] = useState( + Array(userReport.length).fill(false) + ); + + const handleView = (index) => { + setAccordionStates((prevStates) => { + const newStates = [...prevStates]; + newStates[index] = !newStates[index]; + return newStates; + }); }; + return ( <> setOpenModal(false)} - reportObject={reportObject} + userReport={userReport} >

User Reports

-
-
-

- -

-
-
-

- Flowbite is an open-source library of interactive components - built on top of Tailwind CSS including buttons, dropdowns, - modals, navbars, and more. -

-
+

+ +

+
+
+

+ {report?.reason} +

+
+
+
+ ))}
-
-
+ + )} From 4a4e28aa7c2ed0ac287744a9ec839609893a2f08 Mon Sep 17 00:00:00 2001 From: Amarnath AS Date: Sun, 10 Mar 2024 12:13:55 +0530 Subject: [PATCH 51/63] feat: admin user management client side api integration --- .../pages/AdminPages/Managment/Managment.jsx | 84 +++++++++++-------- 1 file changed, 51 insertions(+), 33 deletions(-) diff --git a/client/src/pages/AdminPages/Managment/Managment.jsx b/client/src/pages/AdminPages/Managment/Managment.jsx index 2a95193..b5453dc 100644 --- a/client/src/pages/AdminPages/Managment/Managment.jsx +++ b/client/src/pages/AdminPages/Managment/Managment.jsx @@ -6,18 +6,22 @@ import { toast } from "react-toastify"; function Managment() { const [openModal, setOpenModal] = useState(false); - const [reportObject, setReportObject] = useState(); - const [users, setUsers] = useState([]); + const [userReport, setUserReport] = useState([]); - const handleModal = () => { + const handleModal = (userId) => { + const user = users.find((user) => { + return user._id === userId; + }); + setUserReport(user.reports); setOpenModal(true); }; useEffect(() => { const fetchUsers = async () => { const response = await getUsers(); if (response.success === true) { - setUsers(response.users); + console.log(response.userList); + setUsers(response?.userList); } }; fetchUsers(); @@ -25,8 +29,8 @@ function Managment() { const handleBlock = async (userId) => { const response = await blockUser(userId); - if (response.success === true) { - toast(response.message); + if (response?.success === true) { + toast(response?.message); } }; @@ -35,7 +39,7 @@ function Managment() {
@@ -62,32 +66,46 @@ function Managment() { - - - - - Amarnath as - - Silver - Laptop - - - - - - - - + {users?.map((user, index) => { + return ( + <> + + + + {user?.fullname} + + {user?.email} + {user?.reports.length} + + + + + {user?.is_blocked ? ( + + ) : ( + + )} + + + + + ); + })}
From 196b79be72d364d98c4920aa929b198de4392a27 Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sun, 10 Mar 2024 12:16:37 +0530 Subject: [PATCH 52/63] style: fixed some of the style errors and improved the UI components --- client/src/components/AboutUs/AboutUs.jsx | 52 +- client/src/components/Faq/Faq.jsx | 715 ++++++++++++++++++++ client/src/components/Features/Features.jsx | 280 ++++---- client/src/components/Footer/Footer.jsx | 508 ++------------ client/src/components/Landing/Landing.jsx | 10 +- 5 files changed, 950 insertions(+), 615 deletions(-) create mode 100644 client/src/components/Faq/Faq.jsx diff --git a/client/src/components/AboutUs/AboutUs.jsx b/client/src/components/AboutUs/AboutUs.jsx index 982f383..b475391 100644 --- a/client/src/components/AboutUs/AboutUs.jsx +++ b/client/src/components/AboutUs/AboutUs.jsx @@ -1,3 +1,5 @@ +import { Link } from "react-router-dom"; + export default function AboutUs() { return (

- Brilliant Toolkit to Build Nextgen Website Faster. + What and why Thalia

- The main thrust is to focus on educating attendees on how to - best protect highly vulnerable business applications with - interactive panel discussions and roundtables led by subject - matter experts. + Our vision is to empower women by providing personalized + guidance, reliable learning resources, and a supportive + community, all while prioritizing their safety and + trustworthiness.

- The main thrust is to focus on educating attendees on how to - best protect highly vulnerable business applications with - interactive panel. + We believe that women are like tea bags; their true strength + shines through when faced with challenges. We're here to + empower you. We firmly believe that when women support each + other, amazing things happen.

- Know More - +
@@ -54,19 +57,22 @@ export default function AboutUs() { />
-
-
- - 09 - - - We have - - - Years of experience - + +
+
+ + Join + + + to the wonderful + + + + Community of positivity + +
-
+
diff --git a/client/src/components/Faq/Faq.jsx b/client/src/components/Faq/Faq.jsx new file mode 100644 index 0000000..20361a7 --- /dev/null +++ b/client/src/components/Faq/Faq.jsx @@ -0,0 +1,715 @@ +export default function Faq() { + return ( + <> +
+
+
+
+
+ + It seems good. + +

+ But, ... ? +

+
+
+
+
+
+
+
+ + + + + +
+
+

+ There are many other communities are there. so why Thalia? +

+

+ We have no intention of competing with other communities. + Our sole objective is to address the challenges that women + encounter in society. It's heartening to see other + communities striving towards the same goal. Ultimately, the + fabric of society heavily relies on the contributions of + women. +

+
+
+
+
+ + + + + +
+
+

+ But the Thalia development team is fully male, right ? +

+

+ At first, we thought the same way. But now, our team has + four developers. We realized that having a female team + member isn't crucial as long as we all listen and have + sisters and female friends. Our development team acts as + translators, bringing women's perspectives into the real + world. +

+
+
+
+
+
+
+ + + + + +
+
+

+ Is it possible to create account for male users ? +

+

+ Currently, our website policy doesn't allow male users to + create accounts. If a male user attempts to sign up, they + will be monitored, and our AI bot will likely detect their + actions and block them. +

+
+
+
+
+ + + + + +
+
+

+ Is this an idea only ? +

+

+ No, it's a genuine product that we've developed with + integrity. However, the product isn't perfect yet. We + continue to gather feedback and suggestions from users, + constantly enhancing the app. Please feel free to try it out + for yourself. +

+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + ); +} diff --git a/client/src/components/Features/Features.jsx b/client/src/components/Features/Features.jsx index 8493440..459d166 100644 --- a/client/src/components/Features/Features.jsx +++ b/client/src/components/Features/Features.jsx @@ -1,190 +1,234 @@ +import { Link } from "react-router-dom"; + export default function Features() { return ( -
+
- - Features -

- Main Features Of Play + Core features

-

- There are many variations of passages of Lorem Ipsum available - but the majority have suffered alteration in some form. -

-
-
+
+
- +

- Free and Open-Source + Chatbot (Didi)

- Lorem Ipsum is simply dummy text of the printing and industry. + The app includes a personalised chatbot for you to ask any + questions you want.

- Learn More - +
-
-
+
+
- + + + + + + + + + + + + +

- Multipurpose Template + Community

-

- Lorem Ipsum is simply dummy text of the printing and industry. +

+ Have an incredible community of positive and empowered women, + encouraging support and growth.

- Learn More - +
-
-
+
+
- - - - - - - - - + + + +

- High-quality Design + Informations

- Lorem Ipsum is simply dummy text of the printing and industry. + Discover credible information on mental and physical health to + enhance your well-being and vitality.

- Learn More - +
-
-
+
+
- - - - + + +

- All Essential Elements + Safity

- Lorem Ipsum is simply dummy text of the printing and industry. + Ensure complete safety in chatting and communication. Our + trained AI model detects toxicity in discussions.

- Learn More - +
diff --git a/client/src/components/Footer/Footer.jsx b/client/src/components/Footer/Footer.jsx index 51626b9..9a6c798 100644 --- a/client/src/components/Footer/Footer.jsx +++ b/client/src/components/Footer/Footer.jsx @@ -1,201 +1,22 @@ +import { Link } from "react-router-dom"; import Logo from "../../assets/Logo.svg"; export default function Footer() { return ( <>
-
-
-
-

- logo -

-

- We create digital experiences for brands and companies by - using technology. -

-
-

- - - -

-

- - - -

-

- - - - - -

-

- - - -

-
-
-
-
-
-

- About Us -

-
    -
  • -

    - Home -

    -
  • -
  • -

    - Features -

    -
  • -
  • -

    - About -

    -
  • -
  • -

    - Testimonial -

    -
  • -
-
-
-
-
-

- Features -

-
    -
  • -

    - How it works -

    -
  • -
  • -

    - Privacy policy -

    -
  • -
  • -

    - Terms of Service -

    -
  • -
  • -

    - Refund policy -

    -
  • -
-
-
-
-
-

- Our Products -

-
    -
  • -

    - LineIcons -

    -
  • -
  • -

    - Ecommerce HTML -

    -
  • -
  • -

    - TailAdmin -

    -
  • -
  • -

    - PlainAdmin -

    -
  • -
-
-
-
-
-

- Latest blog -

-
-

-
- blog -
- - I think really important to design with... - -

-

-
- blog -
- - Recognizing the need is the primary... - -

-
-
-
+
+

+ logo +

+

+ "Small acts, when multiplied by millions of people, can transform + the world." +

@@ -205,15 +26,30 @@ export default function Footer() {
-

- Privacy policy -

-

- Legal notice -

-

- Terms of service -

+ + Code of Conduct + + + Contributing + + + LICENCE +
@@ -221,286 +57,18 @@ export default function Footer() {

Designed and Developed by -

- TailGrids and UIdeck -

+ Team Thalia +
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
); diff --git a/client/src/components/Landing/Landing.jsx b/client/src/components/Landing/Landing.jsx index a8756d9..aa56628 100644 --- a/client/src/components/Landing/Landing.jsx +++ b/client/src/components/Landing/Landing.jsx @@ -14,11 +14,13 @@ export default function Landing() { data-wow-delay=".2s" >

- A Platform where community meets empowerment. + “We cannot all succeed when half of us are held back."
+ - Malala Yousafzai

- Welcome to Thalia, your ultimate guide to strength, support, and - sisterhood. + Welcome to Thalia, Here we + are empowering women through proper guidance and a powerful + community.

  • @@ -34,7 +36,7 @@ export default function Landing() { to={"/signup"} className="flex items-center gap-4 rounded-md bg-white/[0.12] px-6 py-[14px] text-base font-medium text-white transition duration-300 ease-in-out hover:bg-primary hover:text-background" > - Siginup + Signup
From b0ea80e7120ecfcf2c636956d56eedb990edb23f Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sun, 10 Mar 2024 12:17:15 +0530 Subject: [PATCH 53/63] style: edited the pages, currected style mistakes --- client/src/pages/UserPages/Home/Home.jsx | 2 ++ client/src/pages/UserPages/Login/Login.jsx | 4 ++-- client/src/pages/UserPages/Signup/Signup.jsx | 14 ++++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/client/src/pages/UserPages/Home/Home.jsx b/client/src/pages/UserPages/Home/Home.jsx index e190024..76f54cc 100644 --- a/client/src/pages/UserPages/Home/Home.jsx +++ b/client/src/pages/UserPages/Home/Home.jsx @@ -3,6 +3,7 @@ import Features from "../../../components/Features/Features"; import Footer from "../../../components/Footer/Footer"; import Landing from "../../../components/Landing/Landing"; import UserHome from "../../../components/UserHome/UserHome"; +import Faq from "../../../components/Faq/Faq"; export default function Home() { const user = localStorage.getItem("user"); @@ -15,6 +16,7 @@ export default function Home() { + )}
diff --git a/client/src/pages/UserPages/Login/Login.jsx b/client/src/pages/UserPages/Login/Login.jsx index efb0c72..d19b014 100644 --- a/client/src/pages/UserPages/Login/Login.jsx +++ b/client/src/pages/UserPages/Login/Login.jsx @@ -117,7 +117,7 @@ export default function Login() { {formError.email} )}
@@ -142,7 +142,7 @@ export default function Login() {
diff --git a/client/src/pages/UserPages/Signup/Signup.jsx b/client/src/pages/UserPages/Signup/Signup.jsx index 12ba837..a20d7d2 100644 --- a/client/src/pages/UserPages/Signup/Signup.jsx +++ b/client/src/pages/UserPages/Signup/Signup.jsx @@ -113,13 +113,13 @@ export default function Signup() { isSubmit={submit} setFormSubmit={setFormSubmit} /> -
+
-

Sigup

+

Signup

{serverError && (
@@ -143,7 +143,7 @@ export default function Signup() { )}
@@ -159,7 +159,7 @@ export default function Signup() { {formError.email} )}
@@ -183,12 +183,14 @@ export default function Signup() {
- Already have account? + + Already have account? +
From ce9f6bc30954fe7deb9838817b449d4518924d00 Mon Sep 17 00:00:00 2001 From: Sreesanjay Date: Sun, 10 Mar 2024 12:19:58 +0530 Subject: [PATCH 54/63] added log in auth middleware --- client/src/App.css | 1 + .../CommunityCard/CommunityCard.jsx | 17 ++- .../src/components/community/NewCommunity.jsx | 116 +++++++++++++++++ .../pages/UserPages/Community/Community.css | 0 .../pages/UserPages/Community/Community.jsx | 123 ++++++++++++++++++ client/src/routes/UserRoute.jsx | 58 +++++---- server/middlewares/authMiddleware.js | 1 + 7 files changed, 288 insertions(+), 28 deletions(-) create mode 100644 client/src/components/community/NewCommunity.jsx create mode 100644 client/src/pages/UserPages/Community/Community.css create mode 100644 client/src/pages/UserPages/Community/Community.jsx diff --git a/client/src/App.css b/client/src/App.css index 25b9795..35a07b9 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -23,3 +23,4 @@ background-color: rgb(74, 29, 86) !important; color: rgb(168, 145, 174) !important; } + diff --git a/client/src/components/CommunityCard/CommunityCard.jsx b/client/src/components/CommunityCard/CommunityCard.jsx index 8951979..891b6a1 100644 --- a/client/src/components/CommunityCard/CommunityCard.jsx +++ b/client/src/components/CommunityCard/CommunityCard.jsx @@ -1,9 +1,14 @@ +import { useNavigate } from "react-router-dom"; import Community from "../../assets/Community.svg"; export default function CommunityCard() { - return ( -
- -

Community

-
- ); + const navigate = useNavigate(); + return ( +
navigate("/community")} + > + +

Community

+
+ ); } diff --git a/client/src/components/community/NewCommunity.jsx b/client/src/components/community/NewCommunity.jsx new file mode 100644 index 0000000..21ad2ee --- /dev/null +++ b/client/src/components/community/NewCommunity.jsx @@ -0,0 +1,116 @@ +import { Modal } from "flowbite-react"; +import { useState } from "react"; +import PropTypes from "prop-types"; + +export default function NewCommunity({ showModal, setShowModal }) { + const [error, setError] = useState(""); + const [formData, setFormData] = useState({ + community_name: "", + privacy: "public", + about: "", + }); + + function handleChange(e) { + const { name, value } = e.target; + setFormData({ ...formData, [name]: value }); + } + + function handleSubmit() { + if (formData.community_name && formData.topic) { + setError(""); + } else if (!formData.community_name) { + setError("Please select a name"); + } else if (!formData.topic) { + setError("Please select a topic"); + } + } + return ( + <> + { + setError(""); + setShowModal(false); + }} + popup + > + +
New Community
+
+ + {error && ( + + {error} + + )} +
+ + +
+
+
+ + +
+
+
+ +

- Safity + ty

Ensure complete safety in chatting and communication. Our From c140d7bb522107fd2253f57f8d3c3f92f5fc67a2 Mon Sep 17 00:00:00 2001 From: Izam Mohammed Date: Sun, 10 Mar 2024 15:22:02 +0530 Subject: [PATCH 63/63] style: currected some grammar mistakes --- client/src/components/Features/Features.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/Features/Features.jsx b/client/src/components/Features/Features.jsx index 816f0b9..d50ad03 100644 --- a/client/src/components/Features/Features.jsx +++ b/client/src/components/Features/Features.jsx @@ -217,7 +217,7 @@ export default function Features() {

- ty + Safety

Ensure complete safety in chatting and communication. Our