Skip to content

Commit

Permalink
done with full blog and publish page
Browse files Browse the repository at this point in the history
  • Loading branch information
pushkar1713 committed Sep 12, 2024
1 parent 43e31c8 commit 39f2d0f
Show file tree
Hide file tree
Showing 16 changed files with 331 additions and 30 deletions.
31 changes: 23 additions & 8 deletions backend/src/routes/posts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,20 @@ postRouter.post("/", async (c) => {
}
const userId = c.get("userId");

const blog = await prisma.post.create({
data: {
title: body.title,
content: body.content,
author_id: userId,
},
});
try {
const blog = await prisma.post.create({
data: {
title: body.title,
content: body.content,
author_id: userId,
},
});

return c.json({ id: blog.id });
return c.json({ id: blog.id, msg: "done" });
} catch (e) {
c.status(411);
return c.json({ msg: "error occured while publishing the blog", error: e });
}
});

postRouter.get("/bulk", async (c) => {
Expand Down Expand Up @@ -86,6 +91,16 @@ postRouter.get("/:id", async (c) => {
where: {
id: id,
},
select: {
content: true,
title: true,
id: true,
author: {
select: {
name: true,
},
},
},
});

return c.json({
Expand Down
30 changes: 30 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"dependencies": {
"@pushkar1713/week13-common": "^1.0.1",
"axios": "^1.7.7",
"jodit-react": "^4.1.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^6.26.1"
Expand Down
Binary file added frontend/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions frontend/src/components/appbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Avatar } from "./blogCard";
import { Link } from "react-router-dom";
import Logo from "../assets/logo.png";

export const Appbar = () => {
return (
<div className="border-b flex justify-between px-10 py-4">
<Link
to={"/blogs"}
className="flex flex-col justify-center cursor-pointer"
>
<img className="w-20" src={Logo} alt="" />
</Link>
<div>
<Link to={`/publish`}>
<button
type="button"
className="mr-4 text-white bg-red-500 hover:bg-green-500 focus:outline-none focus:ring-4 focus:ring-red-300 font-medium rounded-full text-sm px-5 py-2.5 text-center me-2 mb-2 "
>
New
</button>
</Link>

<Avatar size={"big"} name="User" />
</div>
</div>
);
};
65 changes: 49 additions & 16 deletions frontend/src/components/blogCard.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,72 @@
import { Link } from "react-router-dom";

interface blogCardProps {
authorName: String;
title: String;
content: String;
date: String;
id: String;
}

export const BlogCard = ({
id,
authorName,
title,
content,
date,
}: blogCardProps) => {
return (
<div className="flex justify-center p-2">
<div className="w-1/2 border-black border-2">
<div className="flex p-2">
<div className="flex justify-centre flex-col px-2">
<Avatar name={authorName} />
<Link to={`/blog/${id}`}>
<div className="flex justify-center p-2">
<div className="w-1/2 border border-2 max-h-60 overflow-hidden rounded-lg min-h-52">
<div className="flex p-2">
<div className="flex justify-centre flex-col pl-2">
<Avatar name={authorName} />
</div>
<div className="px-2 capitalize">{authorName} </div>
{date}
</div>
<div className="text-2xl font-serif font-medium px-4 capitalize ">
{title}
</div>
<div className="px-4 border-b-2 border-black">{`Reading time : ${Math.ceil(
content.length / 200
)} minutes`}</div>
<div className="px-2">
{content.length > 100 ? (
<div
dangerouslySetInnerHTML={{ __html: content.slice(0, 200) }}
/>
) : (
<div dangerouslySetInnerHTML={{ __html: content }} />
)}
</div>
<div className="px-2">{authorName} </div>
{date}
</div>
<div className="text-3xl font-serif font-semibold ">{title}</div>
<div>{content.length > 100 ? content.slice(0, 200) : content}...</div>
<div>{`Reading time : ${Math.ceil(content.length / 200)} minutes`}</div>
<div className="bg-slate-400 h-1 w-full"></div>
</div>
</div>
</Link>
);
};

const Avatar = ({ name }: { name: String }) => {
export function Avatar({
name,
size = "small",
}: {
name: String;
size?: "small" | "big";
}) {
return (
<div className="relative inline-flex items-center justify-center w-5 h-5 overflow-hidden bg-gray-300 rounded-full">
<span className="font-extralight text-gray-600">{name[0]}</span>
<div
className={`relative inline-flex items-center justify-center overflow-hidden bg-red-500 rounded-full ${
size === "small" ? "w-6 h-6" : "w-10 h-10"
}`}
>
<span
className={`${
size === "small" ? "text-xs" : "text-md"
} font-extralight text-white uppercase`}
>
{name[0]}
</span>
</div>
);
};
}
Empty file.
42 changes: 42 additions & 0 deletions frontend/src/components/fullBlog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Blogs } from "../hooks/hooks";
import { Avatar } from "./blogCard";

export const FullBlog = ({ blog }: { blog: Blogs }) => {
return (
<div>
<div className="flex justify-center">
<div className="grid grid-cols-12 px-10 w-full pt-200 max-w-screen-xl pt-12">
<div className="col-span-8">
<div className="text-5xl font-extrabold capitalize underline font-serif">
{blog.title}
</div>
<div className="text-slate-500 pt-2">
Published on 2nd December 2023
</div>
<div
className="pt-4"
dangerouslySetInnerHTML={{ __html: blog.content }}
/>
</div>
<div className="col-span-4">
<div className="text-slate-600 text-xl underline py-2">Author</div>
<div className="flex w-full">
<div className="pr-4 flex flex-col justify-center">
<Avatar size="big" name={blog.author.name} />
</div>
<div>
<div className="text-xl font-bold capitalize">
{blog.author.name || "Anonymous"}
</div>
<div className=" pt-1 text-slate-500">
Your first blog posts won’t be perfect, but you just have to
do it. You have to start somewhere — Shane Barker
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
Empty file.
24 changes: 23 additions & 1 deletion frontend/src/hooks/useBlog.tsx → frontend/src/hooks/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
import axios from "axios";
import { BACKEND_URL } from "../config";

interface Blogs {
export interface Blogs {
content: string;
title: string;
id: string;
Expand All @@ -11,6 +11,28 @@ interface Blogs {
};
}

export const userBlogs = ({ id }: { id: string }) => {
const [loading, setLoading] = useState(true);
const [blog, setBlog] = useState<Blogs>();

useEffect(() => {
axios
.get(`${BACKEND_URL}/api/v1/blog/${id}`, {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
})
.then((response) => {
setBlog(response.data.blog);
setLoading(false);
});
}, [id]);
return {
loading,
blog,
};
};

export const useBlog = () => {
const [loading, setLoading] = useState(true);
const [blogs, setBlogs] = useState<Blogs[]>([]);
Expand Down
28 changes: 25 additions & 3 deletions frontend/src/pages/blog.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
import { Appbar } from "../components/appbar";
import { FullBlog } from "../components/fullBlog";
import { userBlogs } from "../hooks/hooks";
import { useParams } from "react-router-dom";

// atomFamilies/selectorFamilies
const Blog = () => {
const { id } = useParams();
const { loading, blog } = userBlogs({
id: id || "",
});

if (loading || !blog) {
return (
<div>
<Appbar />
<div className="h-screen flex flex-col justify-center">
<div className="flex justify-center"> loading...</div>
</div>
</div>
);
}
return (
<>
<div>blog</div>
</>
<div>
<Appbar />
<FullBlog blog={blog} />
</div>
);
};

Expand Down
8 changes: 7 additions & 1 deletion frontend/src/pages/blogs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Appbar } from "../components/appbar";
import { BlogCard } from "../components/blogCard";
import { useBlog } from "../hooks/useBlog";
import { useBlog } from "../hooks/hooks";

export const Blogs = () => {
const { loading, blogs } = useBlog();
Expand All @@ -10,12 +11,17 @@ export const Blogs = () => {

return (
<div>
<Appbar />
<h1 className="flex justify-center font-serif font-bold text-4xl p-7 underline decoration-wavy">
Pens and Pixels Blog
</h1>
{blogs.map((blog) => (
<BlogCard
title={blog.title}
content={blog.content}
authorName={blog.author.name}
date="9 September 2002"
id={blog.id}
/>
))}
</div>
Expand Down
Empty file added frontend/src/pages/home.tsx
Empty file.
Loading

0 comments on commit 39f2d0f

Please sign in to comment.