like and unlike post
This commit is contained in:
parent
9e5dc4a740
commit
001cce5374
|
|
@ -17,6 +17,7 @@ model User {
|
|||
password String
|
||||
posts Post[]
|
||||
role Role @default(USER)
|
||||
likes Like[]
|
||||
}
|
||||
|
||||
enum Role {
|
||||
|
|
@ -32,4 +33,14 @@ model Post {
|
|||
author User @relation(fields: [authorId], references: [id])
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
likes Int @default(0)
|
||||
likedBy Like[]
|
||||
}
|
||||
|
||||
model Like {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
postId Int
|
||||
post Post @relation(fields: [postId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import getPosts from './getPosts';
|
|||
import postPost from './newPost';
|
||||
import putPost from './editPost';
|
||||
import deletePost from './deletePost';
|
||||
import likePost from './likePost';
|
||||
import unlikePost from './unlikePost';
|
||||
|
||||
const posts = Router();
|
||||
|
||||
|
|
@ -10,5 +12,7 @@ posts.get('/', getPosts);
|
|||
posts.post('/new', postPost);
|
||||
posts.put('/edit/:id', putPost);
|
||||
posts.delete('/delete/:id', deletePost);
|
||||
posts.put('/like/:id', likePost);
|
||||
posts.put('/unlike/:id', unlikePost);
|
||||
|
||||
export default posts;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import { likePost } from '@/controller/PostController';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
try {
|
||||
const id = parseInt(req.params.id);
|
||||
const userId = 1; // hardcoded for now, use userId from token
|
||||
const likedPost = await likePost(id, userId);
|
||||
if (likedPost instanceof Error) {
|
||||
return res.status(403).send(likedPost.message);
|
||||
}
|
||||
return res.status(200).send({ message: 'Post liked' });
|
||||
} catch (error) {
|
||||
return res.status(500).send(error);
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { unlikePost } from '@/controller/PostController';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export default async (req: Request, res: Response) => {
|
||||
try {
|
||||
const postId = parseInt(req.params.id);
|
||||
const userId = 1; // hardcoded for now, use userId from token
|
||||
const likedPost = await unlikePost(postId, userId);
|
||||
if (likedPost instanceof Error) {
|
||||
return res.status(403).send(likedPost.message);
|
||||
}
|
||||
return res.status(200).send({ message: 'Post unliked' });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
||||
return res.status(500).send(error);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { PrismaClient, Post as PrismaPost, User } from '@prisma/client';
|
||||
import { PrismaClient, Post as PrismaPost, Like } from '@prisma/client';
|
||||
import { Post } from '@/models/PostModel';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
|
@ -15,6 +15,9 @@ const getPostById = async (id: number): Promise<PrismaPost | null> => {
|
|||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
likedBy: true,
|
||||
},
|
||||
});
|
||||
return post;
|
||||
};
|
||||
|
|
@ -23,6 +26,7 @@ const getAllPosts = async (): Promise<PrismaPost[]> => {
|
|||
const posts = prisma.post.findMany({
|
||||
include: {
|
||||
author: true,
|
||||
likedBy: true,
|
||||
},
|
||||
});
|
||||
return (await posts).map((post) => {
|
||||
|
|
@ -90,4 +94,100 @@ const deletePost = async (id: number, userId: number): Promise<PrismaPost | Erro
|
|||
});
|
||||
};
|
||||
|
||||
export { getAllPosts, createPost, editPost, getPostById, deletePost };
|
||||
const unlikePost = async (postId: number, userId: number): Promise<Like | Error> => {
|
||||
const post = await prisma.post.findUnique({
|
||||
where: {
|
||||
id: postId,
|
||||
},
|
||||
include: {
|
||||
likedBy: true,
|
||||
},
|
||||
});
|
||||
if (post === null) {
|
||||
return new Error('Post not found');
|
||||
}
|
||||
const user = await prisma.user.findUnique({
|
||||
where: {
|
||||
id: userId,
|
||||
},
|
||||
include: {
|
||||
likes: true,
|
||||
},
|
||||
});
|
||||
if (user === null) {
|
||||
return new Error('User not found');
|
||||
}
|
||||
const like = post.likedBy.find((likes) => likes.postId === postId && likes.userId === userId);
|
||||
if (like === undefined) {
|
||||
return new Error('Post not liked');
|
||||
}
|
||||
|
||||
await prisma.post.update({
|
||||
where: {
|
||||
id: postId,
|
||||
},
|
||||
data: {
|
||||
likes: {
|
||||
decrement: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return prisma.like.delete({
|
||||
where: {
|
||||
id: like.id,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const likePost = async (id: number, userId: number): Promise<PrismaPost | Error> => {
|
||||
const post = await prisma.post.findUnique({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
include: {
|
||||
likedBy: true,
|
||||
},
|
||||
});
|
||||
if (post === null) {
|
||||
return new Error('Post not found');
|
||||
}
|
||||
// if (post.authorId === userId) {
|
||||
// return new Error('User cannot like their own post');
|
||||
// }
|
||||
if (post.likedBy.some((like) => like.userId === userId)) {
|
||||
return new Error('Post already liked');
|
||||
}
|
||||
const newLike = await prisma.like.create({
|
||||
data: {
|
||||
post: {
|
||||
connect: {
|
||||
id,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
connect: {
|
||||
id: userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return prisma.post.update({
|
||||
where: {
|
||||
id,
|
||||
},
|
||||
data: {
|
||||
likedBy: {
|
||||
connect: {
|
||||
id: newLike.id,
|
||||
},
|
||||
},
|
||||
likes: {
|
||||
increment: 1,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export { getAllPosts, createPost, editPost, getPostById, deletePost, likePost, unlikePost };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import { z } from 'zod';
|
||||
import { User } from './UserModel';
|
||||
import { Post } from './PostModel';
|
||||
|
||||
interface Like {
|
||||
id?: number | undefined;
|
||||
userId: number;
|
||||
user: User;
|
||||
postId: number;
|
||||
post: Post;
|
||||
}
|
||||
|
||||
const Like: z.ZodType<Like> = z.object({
|
||||
id: z.number().optional(),
|
||||
userId: z.number(),
|
||||
user: User,
|
||||
postId: z.number(),
|
||||
post: Post,
|
||||
});
|
||||
|
||||
export { Like };
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
import { z } from 'zod';
|
||||
import { Like } from './LikeModel';
|
||||
|
||||
interface Post {
|
||||
id?: number | undefined;
|
||||
content?: string | undefined;
|
||||
image?: string | undefined;
|
||||
authorId: number;
|
||||
likes?: number | undefined;
|
||||
likedBy?: Like[] | undefined;
|
||||
}
|
||||
|
||||
const Post: z.ZodType<Post> = z.object({
|
||||
|
|
@ -12,6 +15,8 @@ const Post: z.ZodType<Post> = z.object({
|
|||
content: z.string().optional(),
|
||||
image: z.string().optional(),
|
||||
authorId: z.number(),
|
||||
likes: z.number().optional(),
|
||||
likedBy: z.array(Like).optional(),
|
||||
});
|
||||
|
||||
export { Post };
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { z } from 'zod';
|
||||
import { Post } from './PostModel';
|
||||
import { Like } from './LikeModel';
|
||||
|
||||
interface User {
|
||||
id?: number | undefined;
|
||||
|
|
@ -9,6 +10,7 @@ interface User {
|
|||
lastName: string;
|
||||
role?: string | undefined;
|
||||
posts?: Post[] | undefined;
|
||||
likes?: Like[] | undefined;
|
||||
}
|
||||
|
||||
const User: z.ZodType<User> = z.object({
|
||||
|
|
@ -19,6 +21,7 @@ const User: z.ZodType<User> = z.object({
|
|||
lastName: z.string(),
|
||||
role: z.string().optional(),
|
||||
posts: z.array(Post).optional(),
|
||||
likes: z.array(Like).optional(),
|
||||
});
|
||||
|
||||
export { User };
|
||||
|
|
|
|||
Loading…
Reference in New Issue