Skip to content

Commit

Permalink
feat: delete blog
Browse files Browse the repository at this point in the history
  • Loading branch information
RajSanjel committed Jun 24, 2024
1 parent b56c0d2 commit 7c665d6
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/api/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ const API_CONFIG = {
getBlog: `${API_END_POINT}/blog/getBlog`,
getBlogs: `${API_END_POINT}/blog/getBlogs`,
// post req configs
postBlog: `${API_END_POINT}/blog/post`
postBlog: `${API_END_POINT}/blog/post`,

deleteBlog: `${API_END_POINT}/blog/delete`
}

export default API_CONFIG;
7 changes: 2 additions & 5 deletions src/components/Blog.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { formatDate } from "@/utils/formatDate";
import { useEffect, useRef } from "react";
import { Link } from "react-router-dom";

Expand All @@ -10,14 +11,10 @@ type BlogProps = {
}

const Blog = ({ title, author, content, url, postedOn }: BlogProps) => {
const date = new Date(postedOn);
const formattedDate = date.toISOString().split("T")[0]
const contentRef = useRef<HTMLDivElement>(null)

useEffect(() => {
if (contentRef.current != null)
contentRef.current.innerHTML = `${content.split(" ").slice(0, 30).join(" ")}...`;

}, [])

return (
Expand All @@ -33,7 +30,7 @@ const Blog = ({ title, author, content, url, postedOn }: BlogProps) => {
</div>
<span className="text-xs break-words">
By {author}<br />
On {formattedDate}
On {formatDate(postedOn)}
</span>
</div>
</div>
Expand Down
7 changes: 5 additions & 2 deletions src/context/authContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type UserProp = {
name: string,
email: string,
username: string,
userid: string
}

type AuthContextProps = {
Expand All @@ -38,7 +39,7 @@ export function useAuth() {

export function AuthProvider({ children }: any) {
const [isAuth, setIsAuth] = useState(false)
const [user, setUser] = useState<UserProp>({ name: "", email: "", username: "" })
const [user, setUser] = useState<UserProp>({ name: "", email: "", username: "", userid: "" })
const confirmAuth = async () => {
try {
await axios.post(API_CONFIG.verify, {}, { withCredentials: true }).then(res => {
Expand Down Expand Up @@ -104,7 +105,8 @@ export function AuthProvider({ children }: any) {
setUser({
username: data.username,
name: data.name,
email: data.email
email: data.email,
userid: data.userid
})
}
} catch (error) {
Expand All @@ -117,6 +119,7 @@ export function AuthProvider({ children }: any) {
}
}, [isAuth])


return (
<>
<AuthContext.Provider
Expand Down
23 changes: 20 additions & 3 deletions src/context/blogContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import API_CONFIG from "@/api/config";
import axios from "axios";
import axios, { AxiosResponse } from "axios";
import { createContext, useContext } from "react";

type BlogsProp = {
Expand All @@ -13,6 +13,7 @@ type BlogsProp = {
type BlogContext = {
getBlogs: () => Promise<BlogsProp[]>;
getBlog: (url: string) => Promise<BlogsProp>;
deleteBlog: (blogid: string) => Promise<boolean>;
}

const BlogContext = createContext({} as BlogContext)
Expand All @@ -25,6 +26,7 @@ export function useBlogs() {
}

export function BlogProvider({ children }: any) {

async function getBlogs() {
try {
const res = await axios.get(API_CONFIG.getBlogs)
Expand All @@ -50,8 +52,23 @@ export function BlogProvider({ children }: any) {
}
}

return (<BlogContext.Provider value={{ getBlogs, getBlog }}>
const deleteBlog = async (blogid: string) => {
try {
const res: AxiosResponse<any, any> = await axios.post(API_CONFIG.deleteBlog, { blogid }, { withCredentials: true });
if (res.status === 200) {
return true;
}
return false;
} catch (error) {
console.log((error as Error).message)
return false;

}
}


return (<BlogContext.Provider value={{ getBlogs, getBlog, deleteBlog }}>
{children}
</BlogContext.Provider >
)
}
}
79 changes: 71 additions & 8 deletions src/pages/Blog.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,64 @@
import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { useAuth } from "@/context/authContext";
import { useBlogs } from "@/context/blogContext";
import { formatDate } from "@/utils/formatDate"
import { Trash2 } from "lucide-react";
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Navigate, useParams } from "react-router-dom";

export default function Blog() {
function Blog() {
const [blog, setBlog] = useState<any>(null);
const [isOriginalPoster, setIsOriginalPoster] = useState(false);
const [loading, setLoading] = useState(true)
const { slug } = useParams();
const { getBlog } = useBlogs();
const { user, isAuth } = useAuth();
const fetchBlog = async () => {
const res = await getBlog(slug || "");
if (res !== undefined) {
setBlog(res);
setLoading(false)
}

document.title = blog.title
};

const originalPoster = () => {
if (!isAuth) return;
if (!blog) return;
if (blog.userid == user.userid) {
return setIsOriginalPoster(true);
}
setIsOriginalPoster(false);
}

useEffect(() => {
fetchBlog();
}, []);

}, [isAuth]);
useEffect(() => {
originalPoster()
}, [blog]);
return (
<div >
{loading ? <div className="text-center">
Loading blog...
</div> :
!!blog ? (
<section className="container md:w-2/3 w-full mb-3 break-words">
<h1 className="text-4xl font-semibold text-justify">{blog.title}</h1>
<section className="container md:w-2/3 w-full mb-3 break-words grid">
<h1 className="text-4xl font-semibold text-justify">{blog.title}
</h1>
<div className="text-[0.8rem] m-0 p-0 grid grid-flow-col justify-between">
<span>
By {blog.author}<br /> On {formatDate(blog.postedOn)}
</span>
{
isOriginalPoster &&
<span className="grid grid-flow-col gap-3 hover:cursor-pointer items-center justify-start">


<Delete {...blog} />
</span>
}
</div>
<hr className="my-4" />
<div className="text-justify blog mb-8 grid gap-3" dangerouslySetInnerHTML={{ __html: blog.content }} ></div>
</section>
Expand All @@ -39,3 +69,36 @@ export default function Blog() {
</div>
);
}

export function Delete({ blogid }: { blogid: string }) {
const { deleteBlog } = useBlogs();
const [deleted, setDeleted] = useState(false)
const handleClick = async (id: string) => {
const res = await deleteBlog(id)
setDeleted(res)
}
if (deleted) {
return <Navigate to="/blogs" />
}
return (
<Dialog>
<DialogTrigger>
<Trash2 size={18} color="red" />
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle className="text-2xl">Delete Blog</DialogTitle>
<DialogDescription className="text-lg text-salte-950">
Are you sure you want to delete the blog?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button type="submit" className="bg-red-600 hover:bg-red-500" onClick={() => handleClick(blogid)}>Delete</Button>
</DialogFooter>
</DialogContent>
</Dialog>
)
}


export default Blog;
5 changes: 5 additions & 0 deletions src/utils/formatDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const formatDate = (date: string) => {
const toFormatDate = new Date(date);
const formattedDate = toFormatDate.toISOString().split("T")[0]
return formattedDate;
}

0 comments on commit 7c665d6

Please sign in to comment.