From 894cf5a2df954243ed701f556ffdc3d271ab1c92 Mon Sep 17 00:00:00 2001
From: Prabhat Yadav <133522303+Prabhatyadav60@users.noreply.github.com>
Date: Fri, 5 Jul 2024 12:14:07 +0530
Subject: [PATCH 1/5] Update Footer.tsx
---
frontend/src/components/Footer.tsx | 75 ++++++++++++++++++------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx
index 5fc3b72a..ae9e7aa5 100644
--- a/frontend/src/components/Footer.tsx
+++ b/frontend/src/components/Footer.tsx
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
import { loggedInState } from '../store/atoms/auth';
import { CgProfile } from 'react-icons/cg';
import { BsFilePost } from 'react-icons/bs';
-import { FaHome,FaRegCopyright,FaGithub } from 'react-icons/fa';
+import { FaHome, FaRegCopyright, FaGithub, FaEnvelope, FaInfoCircle, FaTools } from 'react-icons/fa';
import { useTranslation } from 'react-i18next';
import logo from "../assets/favicon.png";
@@ -18,14 +18,14 @@ const Footer = () => {
-
-
-
- {t('footer.heading')}
-
-
+
+
+
+ {t('footer.heading')}
+
+
-
+
{t('A simple web-based platform where users can easily contribute, create, explore, share components.')}
@@ -35,13 +35,22 @@ const Footer = () => {
{t('footer.company')}
@@ -49,15 +58,15 @@ const Footer = () => {
{t('footer.quick')}
-
-
- {t('footer.q.q1')}
+
+ {t('footer.q.q1')}
-
-
- {t('footer.q.q2')}
+
+ {t('footer.q.q2')}
@@ -66,31 +75,37 @@ const Footer = () => {
{t('footer.legal')}
-
- {t('footer.l.le1')}
+
+ {t('footer.l.le1')}
+
-
- {t('footer.l.le2')}
+
+ {t('footer.l.le2')}
+
-
- {t('footer.l.le3')}
+
+ {t('footer.l.le3')}
+
-
-
+
+
{t('footer.copy1')} {currentYear} {t('footer.copy2')}
-
+
)
}
From 4e40c48ab0eeb0454078dacfad3e16c8689804e0 Mon Sep 17 00:00:00 2001
From: Prabhat Yadav <133522303+Prabhatyadav60@users.noreply.github.com>
Date: Fri, 5 Jul 2024 15:09:31 +0530
Subject: [PATCH 2/5] added favicons in "legal section"
---
frontend/src/components/Footer.tsx | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx
index ae9e7aa5..129e588b 100644
--- a/frontend/src/components/Footer.tsx
+++ b/frontend/src/components/Footer.tsx
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
import { loggedInState } from '../store/atoms/auth';
import { CgProfile } from 'react-icons/cg';
import { BsFilePost } from 'react-icons/bs';
-import { FaHome, FaRegCopyright, FaGithub, FaEnvelope, FaInfoCircle, FaTools } from 'react-icons/fa';
+import { FaHome, FaRegCopyright, FaGithub, FaEnvelope, FaInfoCircle, FaTools, FaLock, FaFileAlt, FaCookieBite } from 'react-icons/fa';
import { useTranslation } from 'react-i18next';
import logo from "../assets/favicon.png";
@@ -75,17 +75,20 @@ const Footer = () => {
{t('footer.legal')}
-
-
+
+
{t('footer.l.le1')}
-
-
+
+
{t('footer.l.le2')}
-
-
+
+
{t('footer.l.le3')}
From 21d7671480dc6318ee3f2e55dd4604b511dfd5ff Mon Sep 17 00:00:00 2001
From: pani2004
Date: Sat, 6 Jul 2024 00:55:02 +0530
Subject: [PATCH 3/5] Added contributors page
---
frontend/src/App.tsx | 2 +
frontend/src/components/Footer.tsx | 3 ++
frontend/src/pages/Contributors.tsx | 61 +++++++++++++++++++++++++++++
3 files changed, 66 insertions(+)
create mode 100644 frontend/src/pages/Contributors.tsx
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index d6ea8e7c..04d12e58 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -31,6 +31,7 @@ import EditPost from "./pages/EditPost";
import useTheme from './hooks/useTheme';
import CodeEditor from "./pages/CodeEditor";
import TrendingPosts from "./pages/TrendingPosts";
+import Contributors from "./pages/Contributors";
// import axios from "axios";
// axios.defaults.baseURL = "http://localhost:3001/";
@@ -49,6 +50,7 @@ function App() {
} />
} />
} />
+ }/>
} />
{
+ -
+ Our Contributors
+
diff --git a/frontend/src/pages/Contributors.tsx b/frontend/src/pages/Contributors.tsx
new file mode 100644
index 00000000..0863a674
--- /dev/null
+++ b/frontend/src/pages/Contributors.tsx
@@ -0,0 +1,61 @@
+import React, { useEffect, useState } from 'react';
+import axios from 'axios';
+interface Contributor {
+ id: number;
+ login: string;
+ html_url: string;
+ avatar_url: string;
+ contributions: number;
+}
+const Contributors: React.FC = () => {
+ const [contributors, setContributors] = useState
([]);
+ useEffect(() => {
+ async function fetchContributors() {
+ try {
+ const response = await axios.get(
+ 'https://api.github.com/repos/VaibhavArora314/StyleShare/contributors'
+ );
+ setContributors(response.data);
+ } catch (error) {
+ console.error('Error fetching contributors:', error);
+ }
+ }
+ fetchContributors();
+ }, []);
+
+ return (
+
+
+
Contributors
+
+ {contributors.map((contributor) => (
+
+
+
+
+
{contributor.login}
+
+
+ Contributions: {contributor.contributions}
+
+
+ ))}
+
+
+
+ );
+};
+export default Contributors;
+
From 0313aec6f1ae0743eae94f592c7ff1c1581cb732 Mon Sep 17 00:00:00 2001
From: pani2004
Date: Sat, 6 Jul 2024 12:51:09 +0530
Subject: [PATCH 4/5] Made it theme responsive
---
frontend/src/pages/Contributors.tsx | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/frontend/src/pages/Contributors.tsx b/frontend/src/pages/Contributors.tsx
index 0863a674..c5fa88e4 100644
--- a/frontend/src/pages/Contributors.tsx
+++ b/frontend/src/pages/Contributors.tsx
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import axios from 'axios';
+
interface Contributor {
id: number;
login: string;
@@ -7,8 +8,10 @@ interface Contributor {
avatar_url: string;
contributions: number;
}
+
const Contributors: React.FC = () => {
const [contributors, setContributors] = useState([]);
+
useEffect(() => {
async function fetchContributors() {
try {
@@ -24,14 +27,14 @@ const Contributors: React.FC = () => {
}, []);
return (
-
+
Contributors
{contributors.map((contributor) => (
@@ -57,5 +61,6 @@ const Contributors: React.FC = () => {
);
};
+
export default Contributors;
From 8748af8850dca53e2ee907cd41ae8d17edeef27e Mon Sep 17 00:00:00 2001
From: meet
Date: Sun, 7 Jul 2024 23:25:00 +0530
Subject: [PATCH 5/5] Created block/unblock user for admin
---
admin/src/pages/Users.tsx | 292 +++++++++++--------------
backend/prisma/schema.prisma | 1 +
backend/src/routes/admin/controller.ts | 72 +++++-
backend/src/routes/admin/route.ts | 8 +-
4 files changed, 202 insertions(+), 171 deletions(-)
diff --git a/admin/src/pages/Users.tsx b/admin/src/pages/Users.tsx
index 34ae33a3..94f5e1a6 100644
--- a/admin/src/pages/Users.tsx
+++ b/admin/src/pages/Users.tsx
@@ -1,184 +1,138 @@
-import { useState } from "react";
-import Navbar from "../components/Navbar"
+import { useState, useEffect } from "react";
+import axios from "axios";
+import Navbar from "../components/Navbar";
import SideBar from "../components/SideBar";
+import { useRecoilValue } from "recoil";
+import { tokenState } from "../store/atoms/auth";
+import toast from "react-hot-toast";
+
+export interface IUser {
+ id: string;
+ username: string;
+ email: string;
+ verified: boolean;
+ blocked: boolean;
+ createdAt: string;
+ comments:[];
+ posts: [];
+ following: [];
+}
const Users = () => {
const [sidebarOpen, setSidebarOpen] = useState(false);
+ const [allUsers, setAllUsers] = useState([]);
+ const token = useRecoilValue(tokenState);
const toggleSidebar = () => {
setSidebarOpen(!sidebarOpen);
};
+ useEffect(() => {
+ const fetchUsers = async () => {
+ try {
+ const response = await axios.get("/api/v1/admin/allUsers", {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ });
+ setAllUsers(response.data.allUsers.reverse());
+ } catch (error) {
+ console.error("Error fetching users:", error);
+ }
+ };
+
+ fetchUsers();
+ }, [token]);
+
+ const handleBlock = async (userId: string) => {
+ try {
+ const response = await axios.patch(
+ `/api/v1/admin/block/${userId}`,
+ {},
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ toast.success(response.data.message);
+ setAllUsers(allUsers.map(user => user.id === userId ? { ...user, blocked: true } : user));
+ } catch (error) {
+ console.error("Error blocking user:", error);
+ toast.error("Error blocking user");
+ }
+ };
+
+ const handleUnblock = async (userId: string) => {
+ try {
+ const response = await axios.patch(
+ `/api/v1/admin/unblock/${userId}`,
+ {},
+ {
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ toast.success(response.data.message);
+ setAllUsers(allUsers.map(user => user.id === userId ? { ...user, blocked: false } : user));
+ } catch (error) {
+ console.error("Error unblocking user:", error);
+ toast.error("Error unblocking user");
+ }
+ };
+
return (
-
+
-
-
-
-
-
-
- Name
- |
-
- Posts
- |
-
- followers
- |
-
- Action
- |
-
-
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
-
- Neil Sims
- neil.sims@flowbite.com
-
- |
-
- 10
- |
-
- 7
- |
-
-
- |
-
-
-
-
+
+
+
+
+
+ Photo |
+ Name |
+ signup At |
+ Posts |
+ Followers |
+ Comments |
+ Action |
+
+
+
+ {allUsers.map(user => (
+
+ |
+
+
+ {user.username}
+ {user.email}
+
+ |
+ {new Date(user.createdAt).toLocaleDateString()} |
+ {user.posts.length} |
+ {user.following.length} |
+ {user.comments.length} |
+
+ {user.blocked ? (
+
+ ) : (
+
+ )}
+ |
+
+ ))}
+
+
+
- )
-}
+ );
+};
-export default Users
+export default Users;
diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma
index 1f114466..baa0228c 100644
--- a/backend/prisma/schema.prisma
+++ b/backend/prisma/schema.prisma
@@ -19,6 +19,7 @@ model User {
email String
passwordHash String
verified Boolean @default(false)
+ blocked Boolean @default(false)
otp Int?
isAdmin Boolean @default(false)
posts Post[] @relation("authorPosts")
diff --git a/backend/src/routes/admin/controller.ts b/backend/src/routes/admin/controller.ts
index 7a0b7322..496e6fe7 100644
--- a/backend/src/routes/admin/controller.ts
+++ b/backend/src/routes/admin/controller.ts
@@ -75,4 +75,74 @@ export const adminProfileController = async (req: UserAuthRequest, res: Response
res.status(200).json({
user,
});
-};
\ No newline at end of file
+};
+
+export const blockUserController = async (req: Request, res: Response) => {
+ const { userId } = req.params;
+
+ try {
+ const user = await prisma.user.update({
+ where: { id: userId },
+ data: { blocked: true },
+ });
+
+ res.status(200).json({
+ message: `User ${user.username} has been blocked.`,
+ });
+ } catch (error) {
+ res.status(500).json({
+ error: "An unexpected exception occurred!",
+ });
+ }
+};
+
+export const unblockUserController = async (req: Request, res: Response) => {
+ const { userId } = req.params;
+
+ try {
+ const user = await prisma.user.update({
+ where: { id: userId },
+ data: { blocked: false },
+ });
+
+ res.status(200).json({
+ message: `User ${user.username} has been unblocked.`,
+ });
+ } catch (error) {
+ res.status(500).json({
+ error: "An unexpected exception occurred!",
+ });
+ }
+};
+
+export const allUserForAdmin = async (req: Request, res:Response) => {
+ try{
+ const allUsers = await prisma.user.findMany({
+ where: {
+ isAdmin:false
+ },
+ select: {
+ id:true,
+ username:true,
+ email:true,
+ blocked:true,
+ posts:true,
+ createdAt:true,
+ comments:true,
+ following: {
+ select: {
+ id: true
+ }
+ }
+ },
+ });
+ res.status(200).json({
+ message: "Successfully fetched All Users!",
+ allUsers,
+ });
+ }catch(error){
+ res.status(500).json({
+ error: "An unexpected exception occurred!",
+ });
+ }
+}
\ No newline at end of file
diff --git a/backend/src/routes/admin/route.ts b/backend/src/routes/admin/route.ts
index 123a94d7..4fb10648 100644
--- a/backend/src/routes/admin/route.ts
+++ b/backend/src/routes/admin/route.ts
@@ -1,5 +1,5 @@
import {Router} from 'express';
-import { adminLoginController, adminProfileController } from './controller';
+import { adminLoginController, adminProfileController, allUserForAdmin, blockUserController, unblockUserController } from './controller';
import { isAdmin } from '../../middleware/adminAuth';
const adminRouter = Router();
@@ -8,4 +8,10 @@ adminRouter.post("/login", adminLoginController);
adminRouter.get("/me", isAdmin,adminProfileController );
+adminRouter.patch('/block/:userId', isAdmin, blockUserController);
+
+adminRouter.patch('/unblock/:userId', isAdmin, unblockUserController);
+
+adminRouter.get('/allUsers',isAdmin,allUserForAdmin);
+
export default adminRouter;
\ No newline at end of file