+
{myCommunity.map((item, index) => {
return (
{
state.isLoading = false;
@@ -57,12 +52,7 @@ const authSlice = createSlice({
state.isSuccess = true;
state.user = action.payload.user;
localStorage.setItem("user", JSON.stringify(action.payload.user));
- Cookies.set("token", action.payload.token, {
- secure: true,
- sameSite: "none",
- path: '/',
- expires: 3,
- });
+ Cookies.set("token", action.payload.token, { expires: 3, sameSite: 'none', secure: true });
})
.addCase(signUp.rejected, (state, action) => {
state.isLoading = false;
diff --git a/client/src/features/communitySlice.js b/client/src/features/communitySlice.js
index d672c75..c14384a 100644
--- a/client/src/features/communitySlice.js
+++ b/client/src/features/communitySlice.js
@@ -1,5 +1,5 @@
import { createSlice } from "@reduxjs/toolkit";
-import { getMyCommunity, newCommunity } from "../Services/communityService";
+import { getAllCommunity, getMyCommunity, joinCommunity, newCommunity } from "../Services/communityService";
import { toast } from "react-toastify";
@@ -43,7 +43,7 @@ export const communitySlice = createSlice({
})
-
+
//get my community
builder.addCase(getMyCommunity.pending, (state) => {
state.isLoading = true;
@@ -60,53 +60,43 @@ export const communitySlice = createSlice({
})
- // //get all community
- // builder.addCase(getAllCommunity.pending, (state) => {
- // state.isLoading = true;
- // })
- // builder.addCase(getAllCommunity.fulfilled, (state, action) => {
- // state.isLoading = false;
- // state.community = action.payload?.community
- // state.isSuccess = true;
- // })
- // builder.addCase(getAllCommunity.rejected, (state, action) => {
- // state.isError = true;
- // state.isLoading = false;
- // const error = action.payload as {
- // message: string,
- // status: number
- // };
- // state.errorMessage = error.message;
- // state.status = error.status;
+ //get all community
+ builder.addCase(getAllCommunity.pending, (state) => {
+ state.isLoading = true;
+ })
+ builder.addCase(getAllCommunity.fulfilled, (state, action) => {
+ state.isLoading = false;
+ state.community = action.payload?.community
+ state.isSuccess = true;
+ })
+ builder.addCase(getAllCommunity.rejected, (state) => {
+ state.isError = true;
+ state.isLoading = false;
+ toast.error('error while fetching community')
+ })
- // })
+ //join community
+ builder.addCase(joinCommunity.pending, (state) => {
+ state.isLoading = true;
+ })
+ builder.addCase(joinCommunity.fulfilled, (state, action) => {
+ state.isLoading = false;
+ state.community = state.community.map((item) => {
+ if (item._id === action.payload.member.community_id) {
+ item.members.push(action.payload.member);
+ }
+ return item;
+ })
+ state.myCommunity = [{ ...action.payload?.community, members: action.payload?.members }, ...state.myCommunity]
+ state.isSuccess = true;
+ })
+ builder.addCase(joinCommunity.rejected, (state) => {
+ state.isError = true;
+ state.isLoading = false;
+ toast.error('error while joining community')
+ })
- // //join community
- // builder.addCase(joinCommunity.pending, (state) => {
- // state.isLoading = true;
- // })
- // builder.addCase(joinCommunity.fulfilled, (state, action) => {
- // state.isLoading = false;
- // state.community = state.community.map((item) => {
- // if (item._id === action.payload.newMember.community_id) {
- // item.members.push(action.payload.newMember);
- // }
- // return item;
- // })
- // state.myCommunity = [{ ...action.payload?.community, members: action.payload?.members }, ...state.myCommunity]
- // state.isSuccess = true;
- // })
- // builder.addCase(joinCommunity.rejected, (state, action) => {
- // state.isError = true;
- // state.isLoading = false;
- // const error = action.payload as {
- // message: string,
- // status: number
- // };
- // state.errorMessage = error.message;
- // state.status = error.status;
- // })
// //accept join request
// builder.addCase(acceptJoinRequest.pending, (state) => {
// state.isLoading = true;
diff --git a/client/src/pages/UserPages/Community/Community.jsx b/client/src/pages/UserPages/Community/Community.jsx
index f43b770..72d2097 100644
--- a/client/src/pages/UserPages/Community/Community.jsx
+++ b/client/src/pages/UserPages/Community/Community.jsx
@@ -10,6 +10,7 @@ import { useNavigate, useParams } from "react-router-dom";
import NewCommunity from "../../../components/community/NewCommunity";
import RecentDiscussions from "../../../components/community/RecentDiscussions/RecentDiscussions";
import YourCommunity from "../../../components/community/YourCommunity/YourCommunity";
+import DiscoverCommunity from "../../../components/community/DiscoverCommunity/DiscoverCommunity";
export default function Community() {
const { tab } = useParams();
@@ -114,6 +115,8 @@ export default function Community() {
) : currentTab === "YOUR_COMMUNITY" ? (
+ ) : currentTab === "DISCOVER" ? (
+
) : null}
diff --git a/client/src/pages/UserPages/Community/ViewCommunity.css b/client/src/pages/UserPages/Community/ViewCommunity.css
new file mode 100644
index 0000000..0d8ef2a
--- /dev/null
+++ b/client/src/pages/UserPages/Community/ViewCommunity.css
@@ -0,0 +1,6 @@
+.view-community .left-side-bar {
+ height: calc(100vh - 55px);
+}
+.view-community .right-section {
+ height: calc(100vh - 70px);
+}
\ No newline at end of file
diff --git a/client/src/pages/UserPages/Community/ViewCommunity.jsx b/client/src/pages/UserPages/Community/ViewCommunity.jsx
new file mode 100644
index 0000000..bea244d
--- /dev/null
+++ b/client/src/pages/UserPages/Community/ViewCommunity.jsx
@@ -0,0 +1,294 @@
+import { useEffect, useRef, useState } from "react";
+import { useNavigate, useParams } from "react-router-dom";
+import { RiGitRepositoryPrivateFill } from "react-icons/ri";
+import { FaUserPlus } from "react-icons/fa";
+import { FaFileCirclePlus } from "react-icons/fa6";
+import "./ViewCommunity.css";
+import { useDispatch, useSelector } from "react-redux";
+import {
+ getCommunity,
+ getDiscussions,
+ getMyCommunity,
+} from "../../../Services/communityService";
+import DiscussionCard from "../../../components/community/DiscussionCard/DiscussionCard";
+import { resetCommunity } from "../../../features/communitySlice";
+import NewDiscussion from "../../../components/community/NewDiscussion/NewDiscussion";
+
+export default function ViewCommunity() {
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+ const [currentCommunity, setCurrentCommunity] = useState(null);
+ const { user } = useSelector((state) => state.auth);
+ const { id } = useParams();
+ const [discussion, setDiscussion] = useState([]);
+ const [showDropDown, setShowDropDown] = useState("hidden");
+ const pagination = useRef(1);
+ const { myCommunity, isSuccess, isError } = useSelector(
+ (state) => state.community
+ );
+ const [newDiscussion, setNewDiscussion] = useState(false);
+ const [member, setMember] = useState(null);
+
+ async function fetchDiscussion() {
+ if (currentCommunity) {
+ const response = await getDiscussions(
+ currentCommunity._id,
+ pagination.current
+ );
+ if (response.discussions.length > 0) {
+ if (pagination.current === 1) {
+ setDiscussion(response.discussions);
+ } else {
+ setDiscussion([
+ ...discussion,
+ ...response.discussions,
+ ]);
+ }
+ }
+ }
+ }
+
+ useEffect(() => {
+ if (currentCommunity) {
+ fetchDiscussion();
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [currentCommunity]);
+
+ useEffect(() => {
+ if (currentCommunity && user) {
+ const member = currentCommunity.members.filter(
+ (member) => member.user_id === user?._id
+ );
+ setMember(member[0]);
+ }
+ }, [currentCommunity, user]);
+
+ useEffect(() => {
+ if (id) {
+ (async () => {
+ const response = await getCommunity(id);
+ setCurrentCommunity(response.data.community);
+ })();
+ }
+ }, [id]);
+
+ useEffect(() => {
+ dispatch(getMyCommunity());
+ }, [dispatch]);
+ useEffect(() => {
+ dispatch(resetCommunity());
+ }, [isSuccess, isError, dispatch]);
+
+ //scroll handler
+ useEffect(() => {
+ const handleScroll = () => {
+ const bodyHeight = document.body.clientHeight;
+ const scrollHeight = window.scrollY;
+ const innerHeight = window.innerHeight;
+ const isAtBottom = bodyHeight - (scrollHeight + innerHeight) < 1;
+ if (isAtBottom) {
+ if (discussion.length >= pagination.current * 10) {
+ pagination.current = pagination.current + 1;
+ fetchDiscussion();
+ }
+ }
+ };
+ window.addEventListener("scroll", handleScroll);
+ return () => {
+ window.removeEventListener("scroll", handleScroll);
+ };
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [dispatch, discussion]);
+
+ return (
+
+ setShowDropDown("hidden")}
+ >
+
+
Community
+
navigate("/community/discover")}
+ >
+
+ Discover Communities
+
+
+
+
+ Your Communities
+
+ {myCommunity &&
+ myCommunity.map((item, index) => {
+ return (
+
{
+ navigate(
+ `/community/view/${item._id}`
+ );
+ }}
+ >
+
+ {item?.icon ? (
+
+ ) : (
+
+ {item?.community_name[0].toUpperCase()}
+
+ )}
+
+
+
+ {item.community_name}
+
+
+
+ );
+ })}
+
+
+
+
+
+
+ {currentCommunity?.icon ? (
+
+ ) : (
+
+ {currentCommunity?.community_name[0].toUpperCase()}
+
+ )}
+
+
+
setOpenDrawer(true)}
+ >
+ {currentCommunity?.community_name}
+
+
+ {member && member.is_admin && (
+
+ )}
+
+
+
+
+
setOpenMediaUpload(true)}
+ >
+
+
+
+
+
send
+
+
+ {discussion?.map((item, index) => {
+ return (
+
+ );
+ })}
+
+
+
+
About
+
+ {currentCommunity?.about}
+
+
+ {currentCommunity?.privacy === "public" ? (
+
+
Public
+
+ Everyone can see discussions
+
+
+ ) : (
+
+
+
+
+ Private
+
+
+
+ Only the members of this community
+ are allowed to see discussions
+
+
+ )}
+
Activity
+
+
+
+
+
+ {/*
+
+ {currentCommunity && (
+
+ )} */}
+
+ );
+}
diff --git a/client/src/routes/UserRoute.jsx b/client/src/routes/UserRoute.jsx
index 77857e0..6f6b598 100644
--- a/client/src/routes/UserRoute.jsx
+++ b/client/src/routes/UserRoute.jsx
@@ -4,6 +4,7 @@ import Loader from "../components/Loader/Loader1/Loader";
import Authenticate from "../components/Auth/Authenticate";
import Protect from "../components/Auth/Protect";
import Community from "../pages/UserPages/Community/Community";
+import ViewCommunity from "../pages/UserPages/Community/ViewCommunity";
const Home = lazy(() => import("../pages/UserPages/Home/Home"));
const Signup = lazy(() => import("../pages/UserPages/Signup/Signup"));
@@ -46,6 +47,10 @@ export default function UserRoute() {
path={"/community/:tab"}
element={
}
/>
+
}
+ />
diff --git a/server/app.js b/server/app.js
index e0f04a7..ee10246 100644
--- a/server/app.js
+++ b/server/app.js
@@ -9,8 +9,7 @@ const { notFound, errorHandler } = require('./middlewares/errorMiddlewares')
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 ORIGIN = ["http://localhost:4000", 'https://thalia.vercel.app']
+const ORIGIN = process.env.NODE_ENV === 'development' ? "http://localhost:4000" : 'https://thalia.vercel.app'
const corsConfig = {
origin: ORIGIN,
credentials: true,
@@ -25,6 +24,13 @@ app.use(express.json());
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser());
app.use(cors(corsConfig))
+app.use((req, res, next) => {
+ res.setHeader('Access-Control-Allow-Origin', ORIGIN);
+ res.setHeader('Access-Control-Allow-Credentials', true);
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
+ res.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type');
+ next();
+});
//routes
app.use('/api', userRoute)
diff --git a/server/controller/discussion.js b/server/controller/discussion.js
index 28be3a2..ce1aed5 100644
--- a/server/controller/discussion.js
+++ b/server/controller/discussion.js
@@ -187,6 +187,7 @@ const getDiscussions = async (req, res, next) => {
throw new Error('Internal server error')
}
} catch (error) {
+ console.log(error)
next(error.message)
}