From 8af331c37dc951b2bb8e2658438bc3507a716099 Mon Sep 17 00:00:00 2001 From: devsharmag99 Date: Tue, 28 May 2024 08:41:50 +0530 Subject: [PATCH 1/6] feat-#178: added admin UI to frontend feat-#178: rebase to the main --- backend/controllers/user-controller.js | 11 ++- frontend/src/App.tsx | 10 ++- frontend/src/components/admin-sidebar.tsx | 12 ++- frontend/src/layouts/header-layout.tsx | 13 ++++ frontend/src/pages/admin-blogs.tsx | 94 ++++++++++++++++------- frontend/src/pages/admin-users.tsx | 89 ++++++++++++++++++--- 6 files changed, 182 insertions(+), 47 deletions(-) diff --git a/backend/controllers/user-controller.js b/backend/controllers/user-controller.js index dd159131b..930360bba 100644 --- a/backend/controllers/user-controller.js +++ b/backend/controllers/user-controller.js @@ -3,10 +3,13 @@ import User from '../models/user.js'; export const getAllUserHandler = async (req, res) => { try { - const users = await User.find().select('_id name email'); + const users = await User.find().select('_id fullName role email'); return res.status(HTTP_STATUS.OK).json({ users }); } catch (error) { - res.status(HTTP_STATUS.INTERNAL_SERVER_ERROR).json({ message: error.message }); + console.log(error) + res + .status(HTTP_STATUS.INTERNAL_SERVER_ERROR) + .json({ message: RESPONSE_MESSAGES.COMMON.INTERNAL_SERVER_ERROR }); } }; @@ -14,7 +17,7 @@ export const changeUserRoleHandler = async (req, res) => { try { const userId = req.params.userId; const { role } = req.body; - if (role === 'user' || role === 'admin') { + if (role === 'USER' || role === 'ADMIN') { const user = await User.findById(userId); if (!user) return res @@ -29,6 +32,7 @@ export const changeUserRoleHandler = async (req, res) => { } return res.status(HTTP_STATUS.OK).json({ message: RESPONSE_MESSAGES.USERS.UPDATE }); } catch (error) { + console.log(error); res .status(HTTP_STATUS.INTERNAL_SERVER_ERROR) .json({ message: RESPONSE_MESSAGES.COMMON.INTERNAL_SERVER_ERROR, error: error }); @@ -45,6 +49,7 @@ export const deleteUserHandler = async (req, res) => { .json({ message: RESPONSE_MESSAGES.USERS.USER_NOT_EXISTS }); res.status(HTTP_STATUS.NO_CONTENT).json({ message: RESPONSE_MESSAGES.USERS.DELETED }); } catch (error) { + console.log(error); res .status(HTTP_STATUS.INTERNAL_SERVER_ERROR) .json({ message: RESPONSE_MESSAGES.COMMON.INTERNAL_SERVER_ERROR, error: error }); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index acde5d8c8..3b0200f6d 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import HomePage from '@/pages/home-page'; import AddBlog from '@/pages/add-blog'; @@ -13,6 +14,7 @@ import UnprotectedRoute from './components/unprotected-route'; import { useLayoutEffect } from 'react'; import RequireAuth from './components/require-auth'; import useThemeClass from './utils/theme-changer'; +import AdminContainer from './components/admin-container'; function App() { useLayoutEffect(() => { @@ -23,7 +25,7 @@ function App() {
- + } /> } /> }> @@ -34,8 +36,10 @@ function App() { } /> }> - } /> - } /> + }> + } /> + } /> + } /> diff --git a/frontend/src/components/admin-sidebar.tsx b/frontend/src/components/admin-sidebar.tsx index 2b7cd9830..6d65b8c7d 100644 --- a/frontend/src/components/admin-sidebar.tsx +++ b/frontend/src/components/admin-sidebar.tsx @@ -1,4 +1,5 @@ -import { NavLink } from 'react-router-dom'; +import React from 'react'; +import { NavLink, useNavigate } from 'react-router-dom'; import UserIcon from '@/assets/svg/user-icon'; import BlogIcon from '@/assets/svg/blog-icon'; import BarIcons from '@/assets/svg/bars-icon'; @@ -8,6 +9,8 @@ import CloseIcon from '@/assets/svg/close-icon'; const AdminSidebar = () => { const [isSidebarOpen, setIsSidebarOpen] = useState(false); + const navigate = useNavigate(); + return ( <>
-

WanderLust

+

navigate('/')} + className="cursor-pointer text-xl font-medium text-light-title dark:text-dark-title" + > + WanderLust +

{ try { @@ -73,6 +75,17 @@ function header() { ) : token ? (
+ {user?.role === 'ADMIN' && ( + + )} + - -
-
+ {posts?.map((post: Post) => { + return ( +
+ +
+

+ {post?.title} +

+

+ {post?.description} +

+

+ {post?.authorName} • {formatPostTime(post?.timeOfPost)} +

+
+
+ + +
+
+ ); + })}
diff --git a/frontend/src/pages/admin-users.tsx b/frontend/src/pages/admin-users.tsx index 3a815bec2..ba9d60ab4 100644 --- a/frontend/src/pages/admin-users.tsx +++ b/frontend/src/pages/admin-users.tsx @@ -1,4 +1,49 @@ +import React from 'react'; +import axiosInstance from '@/helpers/axios-instance'; +import { useEffect, useState } from 'react'; +import { toast } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; + +interface User { + _id: string; + fullName: string; + role: 'ADMIN' | 'USER'; + email: string; +} + +enum role { + admin = 'ADMIN', + user = 'USER', +} + const AdminUsers = () => { + const [users, setUsers] = useState([]); + + const fetchData = async () => { + try { + const response = await axiosInstance.get('/api/user'); + setUsers(response?.data?.users); + } catch (error) { + toast.error('Something went wrong! Please try again!'); + } + }; + + const handleClick = async (userId: string, role: role) => { + try { + const response = await axiosInstance.patch('/api/user/' + userId, { role: role }); + if (response.status === 200) { + fetchData(); + toast.success('User updated successfully!'); + } + } catch (error) { + toast.error('Something went wrong! Please try again later.'); + } + }; + + useEffect(() => { + fetchData(); + }, []); + return ( <>
@@ -6,17 +51,39 @@ const AdminUsers = () => { Users
-
-
-

Hemant

-

- hemant412@gmail.com -

-
- -
+ {users?.map((user: User) => { + return ( +
+
+

+ {user?.fullName} +

+

+ {user?.email} +

+
+ {user.role === 'ADMIN' && ( + + )} + {user.role === 'USER' && ( + + )} +
+ ); + })}
From e3177a033c8663c3dca1ad9fb35de4a6eb06ac49 Mon Sep 17 00:00:00 2001 From: devsharmag99 Date: Tue, 11 Jun 2024 09:43:16 +0530 Subject: [PATCH 2/6] feat-#178: react import bug fix --- frontend/src/App.tsx | 3 +-- frontend/src/components/admin-sidebar.tsx | 1 - frontend/src/layouts/header-layout.tsx | 1 - frontend/src/pages/admin-blogs.tsx | 1 - frontend/src/pages/admin-users.tsx | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 3b0200f6d..878af5fa2 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { BrowserRouter, Routes, Route } from 'react-router-dom'; import HomePage from '@/pages/home-page'; import AddBlog from '@/pages/add-blog'; @@ -25,7 +24,7 @@ function App() {
- + } /> } /> }> diff --git a/frontend/src/components/admin-sidebar.tsx b/frontend/src/components/admin-sidebar.tsx index 6d65b8c7d..698ae4568 100644 --- a/frontend/src/components/admin-sidebar.tsx +++ b/frontend/src/components/admin-sidebar.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { NavLink, useNavigate } from 'react-router-dom'; import UserIcon from '@/assets/svg/user-icon'; import BlogIcon from '@/assets/svg/blog-icon'; diff --git a/frontend/src/layouts/header-layout.tsx b/frontend/src/layouts/header-layout.tsx index 5cd9ab7b0..43349af09 100644 --- a/frontend/src/layouts/header-layout.tsx +++ b/frontend/src/layouts/header-layout.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import ThemeToggle from '@/components/theme-toggle-button'; import AddIcon from '@/assets/svg/add-icon-white.svg'; import LogOutIcon from '@/assets/svg/logout-icon.svg'; diff --git a/frontend/src/pages/admin-blogs.tsx b/frontend/src/pages/admin-blogs.tsx index 6c303b3b6..1506570d4 100644 --- a/frontend/src/pages/admin-blogs.tsx +++ b/frontend/src/pages/admin-blogs.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import PenIcon from '@/assets/svg/pen-icon'; import TrasnIcon from '@/assets/svg/trash-icon'; import axiosInstance from '@/helpers/axios-instance'; diff --git a/frontend/src/pages/admin-users.tsx b/frontend/src/pages/admin-users.tsx index ba9d60ab4..c94010830 100644 --- a/frontend/src/pages/admin-users.tsx +++ b/frontend/src/pages/admin-users.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import axiosInstance from '@/helpers/axios-instance'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; From 5a191043e0bbf0a884e4c670cc4874d486d254b3 Mon Sep 17 00:00:00 2001 From: devsharmag99 Date: Thu, 13 Jun 2024 08:52:22 +0530 Subject: [PATCH 3/6] feat-#178: enum added --- frontend/src/pages/admin-users.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/admin-users.tsx b/frontend/src/pages/admin-users.tsx index c94010830..7740052bb 100644 --- a/frontend/src/pages/admin-users.tsx +++ b/frontend/src/pages/admin-users.tsx @@ -3,18 +3,18 @@ import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -interface User { - _id: string; - fullName: string; - role: 'ADMIN' | 'USER'; - email: string; -} - enum role { admin = 'ADMIN', user = 'USER', } +type User = { + _id: string; + fullName: string; + role: role; + email: string; +}; + const AdminUsers = () => { const [users, setUsers] = useState([]); @@ -64,7 +64,7 @@ const AdminUsers = () => { {user?.email}

- {user.role === 'ADMIN' && ( + {user.role === role.admin && ( )} - {user.role === 'USER' && ( + {user.role === role.user && (