From 183d2a96fbcdc347c6af4d4a8d0841d7cab82e6f Mon Sep 17 00:00:00 2001 From: mutsinziisaac <85931214+mutsinziisaac@users.noreply.github.com> Date: Wed, 4 Dec 2024 16:30:38 +0300 Subject: [PATCH] #170 An author will be able to update a blog (#171) * fix (170): an author will be able to update a blog * fix (170): allow all users to create and update blogs --- src/models/blogModel.ts | 2 +- src/resolvers/blogResolvers.ts | 74 +++++++++++++++++++++++++++++----- src/schema/blogSchema.ts | 2 + 3 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/models/blogModel.ts b/src/models/blogModel.ts index 34cf865..6b7468a 100644 --- a/src/models/blogModel.ts +++ b/src/models/blogModel.ts @@ -51,7 +51,7 @@ const blogSchema = new Schema({ isHidden: { type: Boolean, - default: false, + default: true, }, author: { type: Schema.Types.ObjectId, diff --git a/src/resolvers/blogResolvers.ts b/src/resolvers/blogResolvers.ts index 3ad4a81..709e1d0 100644 --- a/src/resolvers/blogResolvers.ts +++ b/src/resolvers/blogResolvers.ts @@ -38,6 +38,8 @@ interface UpdateBlogArgs { id: string; title?: string; content?: string; + coverImage?: string; + images?: string[]; tags?: string[]; isHidden?: boolean; } @@ -136,11 +138,6 @@ export const blogResolvers = { if (!userWithRole) { throw new CustomGraphQLError("User not found or not logged in"); } - const roleName = (userWithRole.role as any)?.roleName; - - if (!["applicant", "trainee"].includes(roleName)) { - throw new CustomGraphQLError("Only Trainness can create blogs"); - } try { const existingRecord = await BlogModel.findOne({ title: args.blogFields.title, @@ -167,15 +164,72 @@ export const blogResolvers = { id: { type: new GraphQLNonNull(GraphQLID) }, title: { type: GraphQLString }, content: { type: GraphQLString }, + images: { type: new GraphQLList(GraphQLString) }, + coverImage: { type: GraphQLString }, tags: { type: new GraphQLList(GraphQLString) }, isHidden: { type: GraphQLBoolean }, }, resolve: async ( - _: any, - { id, title, content, tags, isHidden }: UpdateBlogArgs + _: any, + { id, title, content, images, coverImage, tags, isHidden }: UpdateBlogArgs, + context: any ) => { - const updates = { title, content, tags, isHidden }; - return BlogModel.findByIdAndUpdate(id, updates, { new: true }); + // Check if user is logged in and has appropriate role + const userWithRole = await LoggedUserModel.findById( + context.currentUser?._id + ).populate("role"); + + if (!userWithRole) { + throw new CustomGraphQLError("User not found or not logged in"); + } + + try { + // Check if blog exists + const existingBlog = await BlogModel.findById(id); + if (!existingBlog) { + throw new CustomGraphQLError("Blog not found"); + } + + // Optional: Check if user is the original author + if (existingBlog.author.toString() !== context.currentUser?._id.toString()) { + throw new CustomGraphQLError("You can only update your own blogs"); + } + + // Optional: Check for duplicate title (if title is being updated) + if (title) { + const duplicateTitleBlog = await BlogModel.findOne({ + title, + _id: { $ne: id } + }); + + if (duplicateTitleBlog) { + throw new CustomGraphQLError("A blog with this title already exists"); + } + } + + // Prepare updates (only include non-null values) + const updates = Object.fromEntries( + Object.entries({ + title, + content, + images, + coverImage, + tags, + isHidden + }).filter(([_, v]) => v != null) + ); + + // Update blog and return new document + const updatedBlog = await BlogModel.findByIdAndUpdate( + id, + updates, + { new: true } + ); + + return updatedBlog; + } catch (error : any) { + throw new CustomGraphQLError(`Failed to update blog: ${error.message}`); + } }, }, @@ -200,7 +254,7 @@ export const blogResolvers = { const blog = await BlogModel.findById(blogId); if (!blog) { - throw new CustomGraphQLError("Blog not found."); + throw new CustomGraphQLError('Blog not found.'); } blog.isHidden = !blog.isHidden; diff --git a/src/schema/blogSchema.ts b/src/schema/blogSchema.ts index 6ab516c..7a323dd 100644 --- a/src/schema/blogSchema.ts +++ b/src/schema/blogSchema.ts @@ -87,6 +87,8 @@ export const blogSchema = gql` id: ID! title: String content: String + images: [String] + coverImage: String tags: [String] ): Blog! deleteBlog(id: ID!): String!