Skip to content

Commit

Permalink
refactor the code and enhance sending requests to the server .
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed-Ramadan1 committed Jun 1, 2024
1 parent 39f339d commit 7811abd
Show file tree
Hide file tree
Showing 22 changed files with 283 additions and 565 deletions.
38 changes: 14 additions & 24 deletions src/components/blog/BlogForm.jsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
import { Formik, Form } from "formik";
import { useSelector } from "react-redux";
import { toast } from "react-toastify";

import { blogSchema } from "../../schema/blogSchemas";
import { customFetch } from "../../utils/customFetch";

import CustomInput from "../forms/CustomInput";
import CustomDropdownInput from "../forms/CustomDropdownInput";
import CustomTextArea from "../forms/CustomTextArea";
import { sendPostRequest } from "../common/sendRequests";

const BlogForm = ({ setIsChanged }) => {
const { token } = useSelector((state) => state.userReducers);
const createNewBlogPost = async (values) => {
try {
await customFetch.post("blogs", values, {
headers: {
Authorization: `Bearer ${token}`,
},
});

setIsChanged(true);
toast.success("Blog Posted Successfully");
} catch (error) {
toast.error("Failed to Post Blog");
console.log(error);
}
};

return (
<div class="border border-gray-300 p-4 rounded-lg mt-4 md:w-[80%] mx-auto mb-5">
<h2 class="text-3xl mb-2 font-bold italic text-center">Add Post</h2>
Expand All @@ -36,8 +19,15 @@ const BlogForm = ({ setIsChanged }) => {
}}
validationSchema={blogSchema}
onSubmit={(values, actions) => {
createNewBlogPost(values);
actions.resetForm();
sendPostRequest(
"blogs",
values,
"Blog Posted Successfully",
"Failed to Post Blog",
setIsChanged,
actions
);
actions.setSubmitting(false);
}}
>
{({ handleSubmit, isSubmitting }) => (
Expand Down Expand Up @@ -69,10 +59,10 @@ const BlogForm = ({ setIsChanged }) => {
]}
/>
</div>
<div class="flex justify-end mt-5 ">
<div class="flex justify-end mt-5 w-full">
<button
disabled={isSubmitting}
class="bg-blue-500 hover:bg-blue-700 text-white font-medium py-2 px-4 p-5 focus:outline-none focus:shadow-outline rounded-[12px]"
class="bg-blue-500 hover:bg-blue-700 text-white font-bold text-2xl py-2 px-4 p-10 focus:outline-none focus:shadow-outline rounded-[12px] w-full"
type="submit"
>
Blog Now
Expand Down
97 changes: 34 additions & 63 deletions src/components/blog/BlogItem.jsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,12 @@
import { toast } from "react-toastify";
import { customFetch } from "../../utils/customFetch";
import { sendPatchRequest, sendDeleteRequest } from "../common/sendRequests";
import ActionButton from "../userProfile/blogs/ActionButton";

const BlogItem = ({ blog, userId, token, setIsChanged }) => {
const BlogItem = ({ blog, userId, setIsChanged }) => {
const { _id, category, content, createdAt, title, createdBy, visibility } =
blog;
const myBlog = userId === createdBy._id;
const formattedDate = new Date(createdAt).toDateString();

const handelDeleteBlogPost = async () => {
try {
const isConfirmed = window.confirm(
"Are you sure you want to delete this post?"
);
if (!isConfirmed) return;
await customFetch.delete(`blogs/${_id}`, {
headers: {
Authorization: `Bearer ${token}`,
},
});

setIsChanged(true);
toast.success("Blog post deleted successfully");
} catch (error) {
toast.error("Failed to delete blog post");
}
};

const handelMakeItPrivate = async () => {
try {
const isConfirmed = window.confirm(
"Are you sure you want to make this post private no one else you will be able to see the post?"
);
if (!isConfirmed) return;
await customFetch.patch(
`blogs/${_id}`,
{
visibility: "private",
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);

setIsChanged(true);
toast.success(" post visibility converted to private successfully");
} catch (error) {
toast.error("Failed to delete blog post");
}
};

return (
<div class="px-[0vh] md:px-[19vh] my-5">
<div class="border p-3 bg-gray-100 md:rounded-lg rounded-0">
Expand All @@ -65,22 +21,37 @@ const BlogItem = ({ blog, userId, token, setIsChanged }) => {
<p class="text-gray-700 mb-4 ">{content}</p>

{myBlog && (
<div class="flex justify-end">
<button
onClick={handelDeleteBlogPost}
class="bg-red-500
hover:bg-red-700 text-white font-bold py-2 px-4 rounded"
>
Delete
</button>
{visibility === "public" && (
<button
onClick={handelMakeItPrivate}
class="bg-blue-500 ml-2
hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
Make It Private
</button>
<div class="flex justify-end gap-3">
<ActionButton
btnType="danger"
onClick={() => {
sendDeleteRequest(
"Are you sure you want to delete this post?",
`blogs/${_id}`,
"Blog post deleted successfully",
"Failed to delete blog post",
setIsChanged
);
}}
btnText="Delete"
/>
{myBlog && visibility === "public" && (
<ActionButton
btnType="mainBlue"
onClick={() => {
sendPatchRequest(
`blogs/${_id}`,
{
visibility: "private",
},
"Are you sure you want to make this post private no one else you will be able to see the post?",
" post visibility converted to private successfully",
"Failed to Make blog post private",
setIsChanged
);
}}
btnText="Make It Private"
/>
)}
</div>
)}
Expand Down
78 changes: 78 additions & 0 deletions src/components/common/sendRequests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { store } from "../../store/store";
import { toast } from "react-toastify";
import { customFetch } from "../../utils/customFetch";

export const sendPostRequest = async (
endPoint,
data,
successMessage,
failedMessage,
setIsChanged,
actions
) => {
try {
await customFetch.post(endPoint, data, {
headers: {
Authorization: `Bearer ${store.getState().userReducers.token}`,
},
});

setIsChanged(true);
actions.resetForm();
toast.success(successMessage);
} catch (error) {
console.log(error);
toast.error(failedMessage);
}
};

export const sendPatchRequest = async (
endPoint,
data,
confirmText,
successMessage,
failedMessage,
setIsChanged
) => {
const isConfirmed = window.confirm(confirmText);
if (!isConfirmed) return;

try {
await customFetch.patch(endPoint, data, {
headers: {
Authorization: `Bearer ${store.getState().userReducers.token}`,
},
});

setIsChanged(true);
toast.success(successMessage);
} catch (error) {
console.log(error.message);
toast.error(failedMessage);
}
};

export const sendDeleteRequest = async (
confirmText,
endPoint,
successMessage,
failedMessage,
setIsChanged
) => {
const isConfirmed = window.confirm(confirmText);
if (!isConfirmed) return;

try {
await customFetch.delete(endPoint, {
headers: {
Authorization: `Bearer ${store.getState().userReducers.token}`,
},
});

setIsChanged(true);
toast.success(successMessage);
} catch (error) {
console.log(error.message);
toast.error(failedMessage);
}
};
18 changes: 18 additions & 0 deletions src/components/userProfile/blogs/ActionButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const ActionButton = ({ btnType, onClick, btnText }) => {
const colorClass =
btnType === "danger"
? "bg-red-500 hover:bg-red-800"
: btnType === "mainBlue"
? "bg-blue-500 hover:bg-blue-800"
: "";
return (
<button
className={`${colorClass} text-white font-bold py-2 px-4 rounded-[10px] focus:outline-none focus:shadow-outline`}
onClick={onClick}
>
{btnText}
</button>
);
};

export default ActionButton;
Loading

0 comments on commit 7811abd

Please sign in to comment.