Skip to content

Commit

Permalink
Merge pull request #78 from mdazfar2/main
Browse files Browse the repository at this point in the history
u
  • Loading branch information
Ayushmaanagarwal1211 authored Jul 21, 2024
2 parents 0b0d068 + a11acba commit dc65683
Show file tree
Hide file tree
Showing 10 changed files with 912 additions and 37 deletions.
453 changes: 453 additions & 0 deletions Dockerize Spring-boot with Github-Actions/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React, { useContext, useEffect, useState } from "react";
import styles from '@stylesheets/followers.css'
import { Context } from "@context/store";

export default function Followers({ onClose, id }) {
export default function FollowersTab({ setFollowTab,FollowTab,id }) {
const {
finalUser,
setFinalUser,
Expand Down Expand Up @@ -67,7 +66,13 @@ export default function Followers({ onClose, id }) {
setFinalUser(updatedData.user1);
localStorage.setItem('finalUser', JSON.stringify(updatedData.user1));
}

function handleClose(){
if(FollowTab){
setFollowTab(false);
}else{
setFollowTab(true);
}
}
return (
<>
<div className="auth-overlay">
Expand All @@ -94,7 +99,7 @@ export default function Followers({ onClose, id }) {
{userDetails.followers && Object.entries(userDetails.followers).map(([userId, [userImg, userName]]) =>{
if(userId!==finalUser._id){

return <div id={userId} className="w-[100%] mt-[20px] h-[60px] font-cursive items-center flex justify-between pl-[10px] pr-[10px] overflow-hidden">
return <div id={userId} className="w-[100%] mt-[20px] h-[60px] items-center flex justify-between pl-[10px] pr-[10px] overflow-hidden">
<img height='60px' width='60px' className="rounded-full" src={userImg}></img>
<h1 className={`text-wrap text-center ${theme ? "text-black" : "text-white"}`}>{userName}</h1>
{(userId in finalUser.following) ?
Expand All @@ -108,7 +113,7 @@ export default function Followers({ onClose, id }) {
<div className={`${firstShow ? "coming3" : "coming1"} h-[42vh] overflow-y-scroll w-[100%] div-animate`}>
{userDetails.following && Object.entries(userDetails.following).map(([userId, [userImg, userName]]) => (
userId !== finalUser._id &&
<div key={userId} className="w-[100%] h-[60px] font-cursive items-center flex justify-between pl-[10px] pr-[10px] overflow-hidden">
<div key={userId} className="w-[100%] h-[60px] items-center flex justify-between pl-[10px] pr-[10px] overflow-hidden">
<img height='60px' width='60px' className="rounded-full" src={userImg}></img>
<h1 className={`text-wrap text-center ${theme ? "text-black" : "text-white"}`}>{userName}</h1>
{(userId in finalUser.following) ?
Expand All @@ -120,7 +125,7 @@ export default function Followers({ onClose, id }) {
</div>
</div>
</div>
<div className="fixed top-0 left-0 h-[100vh] w-[100vw] opacity-35 bg-black" onClick={onClose}></div>
<div className="fixed top-0 left-0 h-[100vh] w-[100vw] opacity-35 bg-black" onClick={handleClose}></div>
</div>
</>
);
Expand Down
86 changes: 86 additions & 0 deletions website3.0/components/profile/GrowYourReachTab.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { useContext, useEffect, useState } from "react";
import { Context } from "@context/store";
import { useRouter } from "next/navigation";

function GrowYourReachTab() {
const { finalUser, theme } = useContext(Context);
const [nonFollowers, setNonFollowers] = useState([]);
const router = useRouter();

useEffect(() => {
const fetchAllUsers = async () => {
try {
const response = await fetch("/api/alluser", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});

if (response.ok) {
const data = await response.json();
const allUsers = data.msg;

console.log("All users:", allUsers);

if (finalUser && finalUser.following) {
const followingIds = Object.keys(finalUser.following);
console.log("Following IDs:", followingIds);

const nonFollowersList = allUsers.filter(
user => !followingIds.includes(user._id) && user._id !== finalUser._id
);

console.log("Non-followers list:", nonFollowersList);

setNonFollowers(nonFollowersList);
}
} else {
console.error("Error fetching all users:", response.statusText);
}
} catch (error) {
console.error("Error fetching all users:", error);
}
};

fetchAllUsers();
}, [finalUser]);

const handleFollowClick = (userId) => {
router.push(`/profile?id=${userId}`);
};

return (
<div className="h-screen p-10">
<div className= {`${theme?"bg-gray-100 text-black":"bg-[#111111] text-white"} w-full rounded-xl min-h-96 text-2xl text-center p-5`}>
Grow Your Reach
<div className="mt-10 text-xl">
{nonFollowers.length > 0 ? (
<ul>
{nonFollowers.map(user => (
<li key={user._id} className={`${theme?"bg-gray-200 text-black":"bg-[#383838] text-white"} py-3 px-2 rounded-xl mb-2 flex justify-between items-center`}>
<div className="flex items-center">
<img src={user.image1} alt={user.name} className="w-10 h-10 rounded-full inline-block mr-3" />
{user.name}
</div>
<a
href={`/profile?id=${user._id}`}
target="_blank"
rel="noopener noreferrer"
className={`${theme?"bg-[#6089a4]":"bg-[#979797]"} text-lg max-md:text-sm text-white px-4 py-2 rounded-md`}
>
Open Profile
</a>
</li>
))}
</ul>
) : (
<p>No new users to Show.</p>
)}
</div>
</div>
</div>
);
}

export default GrowYourReachTab;
206 changes: 206 additions & 0 deletions website3.0/components/profile/NotificationTab.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
"use client";
import React, { useContext, useEffect, useState } from "react";
import { Context } from "@context/store";
import Link from 'next/link';
function NotificationTab() {
const { finalUser,theme } = useContext(Context);
const [notifications, setNotifications] = useState({
followers: [],
blogs: [],
});

useEffect(() => {
if (!finalUser || !finalUser.email) return;

const updateNotifications = async () => {
try {
// Fetch user data
const response = await fetch("/api/getuserbyemail", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email: finalUser.email }),
});

if (response.ok) {
const userData = await response.json();
const followers = userData.msg.followers;

// Fetch existing notifications
const checkResponse = await fetch(
`/api/notifications?userEmail=${finalUser.email}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
}
);

let existingNotifications = { followerList: {}, blogList: {} };

if (checkResponse.ok) {
existingNotifications = await checkResponse.json();
} else if (checkResponse.status === 404) {
console.log("No existing notifications found. Creating new ones.");
} else {
console.error(
"Error fetching existing notifications:",
checkResponse.statusText
);
return;
}

const { followerList = {}, blogList = {} } = existingNotifications;

// Handle follower notifications
const updatedFollowers = await Promise.all(
Object.entries(followerList).map(async ([followerId, details]) => {
const userResponse = await fetch("/api/getuser", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ id: followerId }),
});

if (userResponse.ok) {
const userData = await userResponse.json();
const followerName = userData.msg.name;
return {
followerId,
followerName,
dateTime: details.dateTime,
};
}
return {
followerId,
followerName: "Unknown",
dateTime: details.dateTime,
};
})
);

// Handle blog notifications
const blogResponse = await fetch("/api/blog", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});

let latestBlogId = null;
let blogDataMap = {};

if (blogResponse.ok) {
const blogs = await blogResponse.json();
blogDataMap = blogs.data.reduce((map, blog) => {
map[blog._id] = blog;
return map;
}, {});

if (blogs.data.length > 0) {
latestBlogId = blogs.data[blogs.data.length - 1]._id;
const isNewBlog = !Object.keys(blogList).includes(latestBlogId);

if (isNewBlog) {
const response2 = await fetch("/api/notifications", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userEmail: finalUser.email,
blogId: latestBlogId,
}),
});

console.log("New blog notification sent:", response2.ok);
}
}
}

setNotifications({
followers: updatedFollowers,
blogs: Object.entries(blogList).map(([blogId, details]) => ({
blogId,
blogName: blogDataMap[blogId]?.title || "Unknown Blog",
dateTime: details.dateTime,
})),
});
// Handle new follower notifications
for (const followerId in followers) {
if (followers.hasOwnProperty(followerId)) {
const isDuplicate =
Object.keys(followerList).includes(followerId);

if (!isDuplicate) {
const response2 = await fetch("/api/notifications", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userEmail: finalUser.email,
followerId,
}),
});

console.log("New follower notification sent:", response2.ok);
} else {
console.log(
"Duplicate follower notification found, not sending again."
);
}
}
}
} else {
console.error("Error fetching user data:", response.statusText);
}
} catch (error) {
console.error("Error updating notifications:", error);
}
};

const interval = setInterval(updateNotifications, 1000);

return () => clearInterval(interval);
}, [finalUser]);

return (
<div className="h-screen p-4">
<div className={`${theme?"bg-gray-100 text-black":"bg-[#111111] text-white"} p-4 rounded-xl flex flex-col gap-4 `}>
<h2 className="text-xl text-center">Notifications</h2>
<hr className={`${theme?"border-gray-300 text-black":"bg-[#3c3c3c] text-white"} w-full border-2 my-4`} />
<ul>
{notifications.followers.map(
({ followerId, followerName, dateTime }) => (
<Link href={`/profile?id=${followerId}`} key={followerId} target="_blank">
<li key={followerId} className={`${theme?"bg-gray-200 text-black":"bg-[#3c3c3c] text-white"} py-3 px-2 rounded-xl `}>
{followerName} has started following you.{" "}
({new Date(dateTime).toLocaleString()})
</li>
</Link>
)
)}
</ul>
<ul className="flex flex-col gap-4 ">
{notifications.blogs.map(({ blogId, blogName, dateTime }) => (
<Link href={`/blogs/${blogId}`} key={blogId} target="_blank">
<li key={blogId} className={`${theme?"bg-gray-200 text-black":"bg-[#3c3c3c] text-white"} py-3 px-2 rounded-xl`}>
<span className="flex gap-1">
Read a blog on the topic{" "}
<span dangerouslySetInnerHTML={{ __html: blogName }}></span>
({new Date(dateTime).toLocaleString()})
</span>
</li>
</Link>
))}
</ul>
</div>
</div>
);
}

export default NotificationTab;
Loading

0 comments on commit dc65683

Please sign in to comment.