From f3708b9fe182dd28578d6863da2b31b473f4d7ea Mon Sep 17 00:00:00 2001 From: meet Date: Sat, 6 Jul 2024 19:23:14 +0530 Subject: [PATCH 1/3] Fetching new and trending posts --- admin/src/components/NewPosts.tsx | 111 ++++++++------------ admin/src/components/TrendingPosts.tsx | 138 ++++++++++--------------- admin/src/types.ts | 33 ++++++ backend/src/routes/post/controller.ts | 8 ++ backend/src/routes/post/route.ts | 5 - frontend/src/App.tsx | 4 +- 6 files changed, 143 insertions(+), 156 deletions(-) create mode 100644 admin/src/types.ts diff --git a/admin/src/components/NewPosts.tsx b/admin/src/components/NewPosts.tsx index 3edcd1b2..47259489 100644 --- a/admin/src/components/NewPosts.tsx +++ b/admin/src/components/NewPosts.tsx @@ -1,6 +1,24 @@ import { PiNewspaperClippingLight } from "react-icons/pi" +import axios from "axios"; +import { useEffect, useState } from "react"; +import { IPost } from '../types'; const NewPosts = () => { + const [posts, setposts] = useState([]); + + const fetchPost = async () => { + try { + const response = await axios.get('/api/v1/posts?page=1&pageSize=6'); + setposts(response.data.posts.reverse()); + // console.log(response.data.posts); + } catch (error) { + console.log(error); + } + }; + + useEffect(() => { + fetchPost(); + }, []); return (
@@ -11,84 +29,41 @@ const NewPosts = () => { New Posts
-
- +
+
- - - - - - - - + + + + + + + + - - - - - - - - - - - + + - - - - + + + + + ))}
- Title - - Author - - createdAt - - Likes - - Comments - - Action -
TitleAuthorCreated AtCommentsReactionsAction
- Navbar component - -
-
Neil Sims
-
neil.sims@flowbite.com
-
-
- 10th June 2024 - - 7 - - 7 - - -
- Navbar component - + {posts.slice(0,6).map(posts => ( +
{posts.title}
-
Neil Sims
-
neil.sims@flowbite.com
-
-
- 10th June 2024 - - 7 - - 7 - +
{posts.author.username}
+
{posts.author.email}
+ + +
{new Date(posts.createdAt).toLocaleDateString()}{posts.comments.length}{posts.reactions.length} -
-
+
) } diff --git a/admin/src/components/TrendingPosts.tsx b/admin/src/components/TrendingPosts.tsx index 848153bd..5268e3eb 100644 --- a/admin/src/components/TrendingPosts.tsx +++ b/admin/src/components/TrendingPosts.tsx @@ -1,96 +1,72 @@ +import axios from "axios"; +import { useEffect, useState } from "react"; import { MdAutoGraph } from "react-icons/md"; +import { IPost } from '../types'; const TrendingPosts = () => { + const [trendingPosts, setTrendingPosts] = useState([]); + + const fetchPost = async () => { + try { + const response = await axios.get('/api/v1/posts/trending'); + setTrendingPosts(response.data.trendingPosts); + // console.log(response.data.trendingPosts); + } catch (error) { + console.log(error); + } + }; + + useEffect(() => { + fetchPost(); + }, []); + return (
-
+
-
- -
- Trending Posts +
+ +
+ Trending Posts
-
-
- - + +
+
+ - - - - - - - - - - - - - - - - + + + + + + - - + + + {trendingPosts.slice(0,6).map(post => ( + + - - + + + - - - - -
- Title - - Author - - createdAt - - Likes - - Comments - - Action -
- Navbar component - -
-
Neil Sims
-
neil.sims@flowbite.com
-
-
- 10th June 2024 - - 7 - - 7 - - - TitleAuthorCreated AtCommentsReactionsAction
- Navbar component -
{post.title} -
-
Neil Sims
-
neil.sims@flowbite.com
-
+
+
{post.author.username}
+
{post.author.email}
+
- 10th June 2024 - - 7 + {new Date(post.createdAt).toLocaleDateString()}{post.comments.length}{post.reactions.length} + - 7 - - -
+ + ))} + +
- ) -} + ); +}; -export default TrendingPosts +export default TrendingPosts; diff --git a/admin/src/types.ts b/admin/src/types.ts new file mode 100644 index 00000000..c92034ce --- /dev/null +++ b/admin/src/types.ts @@ -0,0 +1,33 @@ +export interface IPost { + id: string; + title: string; + description: string; + codeSnippet: string; + jsCodeSnippet: string; + tags: string[]; + createdAt:number; + author: { + id: string; + username: string; + email: string; + totalFollowers:number + }, + comments:[] + reactions:[]; + favoritePosts: []; + userReaction: 'Like' | 'Celebrate' | 'Support' | 'Love' | 'Insightful' | 'Funny' | null; + } + + export interface IUser { + id: string; + username: string; + email: string; + verified: boolean; + createdAt:string; + posts: IPost[]; + favoritePosts?: IPost[]; + isFollowing: boolean; + _count: { + following: number + } + } \ No newline at end of file diff --git a/backend/src/routes/post/controller.ts b/backend/src/routes/post/controller.ts index fb0cbc03..a06d7ddd 100644 --- a/backend/src/routes/post/controller.ts +++ b/backend/src/routes/post/controller.ts @@ -279,10 +279,15 @@ export const getPostsWithPagination = async (req: Request, res: Response) => { jsCodeSnippet: true, description: true, tags: true, + likes:true, + createdAt:true, + comments:true, + reactions:true, author: { select: { id: true, username: true, + email:true }, }, }, @@ -323,6 +328,9 @@ export const getTrendingPostsController = async (req: Request, res: Response) => jsCodeSnippet: true, description: true, tags: true, + likes:true, + createdAt:true, + comments:true, author: { select: { id: true, diff --git a/backend/src/routes/post/route.ts b/backend/src/routes/post/route.ts index 1bac5f1b..1da7e529 100644 --- a/backend/src/routes/post/route.ts +++ b/backend/src/routes/post/route.ts @@ -1,13 +1,8 @@ import { Router } from "express"; import authMiddleware from "../../middleware/auth" - - - - import { getTrendingPostsController,aiCustomization, createCommentController, createPostController, deletePostController, favoritePostController, getAllTagsController, getCommentsController, getFavoritePostsController, getLeaderboardController, getPostController, getPostReactionsController, getPostsWithPagination, getUserReactionController, reactToPostController, removeReactionController, unfavoritePostController, updatePostController } from "./controller"; - const postRouter = Router(); postRouter.get('/', getPostsWithPagination); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d7e8a19a..d6ea8e7c 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -31,8 +31,8 @@ import EditPost from "./pages/EditPost"; import useTheme from './hooks/useTheme'; import CodeEditor from "./pages/CodeEditor"; import TrendingPosts from "./pages/TrendingPosts"; -import axios from "axios"; -axios.defaults.baseURL = "http://localhost:3001/"; +// import axios from "axios"; +// axios.defaults.baseURL = "http://localhost:3001/"; function App() { const { theme, toggleTheme } = useTheme(); From 4c25afc333a849faeca2dc05b64e655039a0bdd1 Mon Sep 17 00:00:00 2001 From: meet Date: Sun, 7 Jul 2024 16:43:43 +0530 Subject: [PATCH 2/3] Reset the posts backend api and created admin api for allposts and trendingposts --- admin/src/components/NewPosts.tsx | 11 ++++- admin/src/components/TrendingPosts.tsx | 9 +++- backend/src/routes/admin/controller.ts | 63 ++++++++++++++++++++++++++ backend/src/routes/admin/route.ts | 6 ++- backend/src/routes/post/controller.ts | 8 ---- 5 files changed, 85 insertions(+), 12 deletions(-) diff --git a/admin/src/components/NewPosts.tsx b/admin/src/components/NewPosts.tsx index 47259489..34117fe1 100644 --- a/admin/src/components/NewPosts.tsx +++ b/admin/src/components/NewPosts.tsx @@ -2,15 +2,22 @@ import { PiNewspaperClippingLight } from "react-icons/pi" import axios from "axios"; import { useEffect, useState } from "react"; import { IPost } from '../types'; +import { useRecoilValue } from "recoil"; +import { tokenState } from "../store/atoms/auth"; const NewPosts = () => { const [posts, setposts] = useState([]); + const token = useRecoilValue(tokenState); const fetchPost = async () => { try { - const response = await axios.get('/api/v1/posts?page=1&pageSize=6'); + const response = await axios.get('/api/v1/admin/getAdminAllPosts',{ + headers: { + Authorization: `Bearer ${token}`, + }, + }); setposts(response.data.posts.reverse()); - // console.log(response.data.posts); + console.log(response.data.posts); } catch (error) { console.log(error); } diff --git a/admin/src/components/TrendingPosts.tsx b/admin/src/components/TrendingPosts.tsx index 5268e3eb..3b4e11da 100644 --- a/admin/src/components/TrendingPosts.tsx +++ b/admin/src/components/TrendingPosts.tsx @@ -2,13 +2,20 @@ import axios from "axios"; import { useEffect, useState } from "react"; import { MdAutoGraph } from "react-icons/md"; import { IPost } from '../types'; +import { tokenState } from "../store/atoms/auth"; +import { useRecoilValue } from "recoil"; const TrendingPosts = () => { const [trendingPosts, setTrendingPosts] = useState([]); + const token = useRecoilValue(tokenState); const fetchPost = async () => { try { - const response = await axios.get('/api/v1/posts/trending'); + const response = await axios.get('/api/v1/admin/getAdminAllTrendingPosts',{ + headers: { + Authorization: `Bearer ${token}`, + }, + }); setTrendingPosts(response.data.trendingPosts); // console.log(response.data.trendingPosts); } catch (error) { diff --git a/backend/src/routes/admin/controller.ts b/backend/src/routes/admin/controller.ts index 7a0b7322..209dac1c 100644 --- a/backend/src/routes/admin/controller.ts +++ b/backend/src/routes/admin/controller.ts @@ -75,4 +75,67 @@ export const adminProfileController = async (req: UserAuthRequest, res: Response res.status(200).json({ user, }); +}; + +export const getAdminPostsController = async (req: Request, res: Response) => { + const posts = await prisma.post.findMany({ + select: { + id: true, + title: true, + codeSnippet: true, + jsCodeSnippet: true, + description: true, + tags: true, + createdAt:true, + comments:true, + reactions:true, + author: { + select: { + id: true, + username: true, + email: true, + }, + }, + }, + }); + + res.status(200).json({ + posts, + }); +}; + +export const getAdminTrendingPostsController = async (req: Request, res: Response) => { + try{ + const trendingPosts = await prisma.post.findMany({ + select: { + id: true, + title: true, + codeSnippet: true, + jsCodeSnippet: true, + description: true, + tags: true, + likes:true, + createdAt:true, + comments:true, + author: { + select: { + id: true, + username: true, + email: true, + }, + }, + reactions:true, + }, + }); + res.status(200).json({ + message: "Successfully created comment!", + trendingPosts, + }); + + + }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..0c1bc3a7 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, getAdminPostsController, getAdminTrendingPostsController } from './controller'; import { isAdmin } from '../../middleware/adminAuth'; const adminRouter = Router(); @@ -8,4 +8,8 @@ adminRouter.post("/login", adminLoginController); adminRouter.get("/me", isAdmin,adminProfileController ); +adminRouter.get("/getAdminAllPosts", isAdmin,getAdminPostsController ); + +adminRouter.get("/getAdminAllTrendingPosts", isAdmin,getAdminTrendingPostsController ); + export default adminRouter; \ No newline at end of file diff --git a/backend/src/routes/post/controller.ts b/backend/src/routes/post/controller.ts index a06d7ddd..fb0cbc03 100644 --- a/backend/src/routes/post/controller.ts +++ b/backend/src/routes/post/controller.ts @@ -279,15 +279,10 @@ export const getPostsWithPagination = async (req: Request, res: Response) => { jsCodeSnippet: true, description: true, tags: true, - likes:true, - createdAt:true, - comments:true, - reactions:true, author: { select: { id: true, username: true, - email:true }, }, }, @@ -328,9 +323,6 @@ export const getTrendingPostsController = async (req: Request, res: Response) => jsCodeSnippet: true, description: true, tags: true, - likes:true, - createdAt:true, - comments:true, author: { select: { id: true, From 474b356acf026e3f8dc1456b8603dd12f5020c68 Mon Sep 17 00:00:00 2001 From: meet Date: Mon, 8 Jul 2024 11:31:12 +0530 Subject: [PATCH 3/3] Changes done as per request --- admin/src/components/NewPosts.tsx | 3 +-- admin/src/components/TrendingPosts.tsx | 3 +-- backend/src/routes/admin/route.ts | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/admin/src/components/NewPosts.tsx b/admin/src/components/NewPosts.tsx index 34117fe1..80f8c082 100644 --- a/admin/src/components/NewPosts.tsx +++ b/admin/src/components/NewPosts.tsx @@ -11,13 +11,12 @@ const NewPosts = () => { const fetchPost = async () => { try { - const response = await axios.get('/api/v1/admin/getAdminAllPosts',{ + const response = await axios.get('/api/v1/admin/posts/all',{ headers: { Authorization: `Bearer ${token}`, }, }); setposts(response.data.posts.reverse()); - console.log(response.data.posts); } catch (error) { console.log(error); } diff --git a/admin/src/components/TrendingPosts.tsx b/admin/src/components/TrendingPosts.tsx index 3b4e11da..d707cba7 100644 --- a/admin/src/components/TrendingPosts.tsx +++ b/admin/src/components/TrendingPosts.tsx @@ -11,13 +11,12 @@ const TrendingPosts = () => { const fetchPost = async () => { try { - const response = await axios.get('/api/v1/admin/getAdminAllTrendingPosts',{ + const response = await axios.get('/api/v1/admin/posts/trending',{ headers: { Authorization: `Bearer ${token}`, }, }); setTrendingPosts(response.data.trendingPosts); - // console.log(response.data.trendingPosts); } catch (error) { console.log(error); } diff --git a/backend/src/routes/admin/route.ts b/backend/src/routes/admin/route.ts index 0c1bc3a7..8936afef 100644 --- a/backend/src/routes/admin/route.ts +++ b/backend/src/routes/admin/route.ts @@ -8,8 +8,8 @@ adminRouter.post("/login", adminLoginController); adminRouter.get("/me", isAdmin,adminProfileController ); -adminRouter.get("/getAdminAllPosts", isAdmin,getAdminPostsController ); +adminRouter.get("/posts/all", isAdmin,getAdminPostsController ); -adminRouter.get("/getAdminAllTrendingPosts", isAdmin,getAdminTrendingPostsController ); +adminRouter.get("/posts/trending", isAdmin,getAdminTrendingPostsController ); export default adminRouter; \ No newline at end of file