Skip to content

Commit

Permalink
layout
Browse files Browse the repository at this point in the history
  • Loading branch information
shivaydv committed Nov 7, 2024
1 parent b5df4fe commit f2914bb
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 165 deletions.
23 changes: 11 additions & 12 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,17 @@ model User {
}

model Post {
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
description String
content String
slug String @unique
published Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
bannerImage String?
category String?
comments Comment[]
likes Like[]
id String @id @default(auto()) @map("_id") @db.ObjectId
title String
description String
content String
bannerImage String
slug String @unique
published Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
likes Like[]
comments Comment[]
}

model Comment {
Expand Down
9 changes: 2 additions & 7 deletions src/actions/postActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const Blogschema = z.object({
title: z.string().min(1, { message: "Title is required" }),
description: z.string().min(1, { message: "Description is required" }),
content: z.string().min(1, { message: "Content is required" }),
category: z.string().min(1, { message: "Category is required" }),
bannerImage: z.string().min(1, { message: "Banner image is required" }),
});

Expand All @@ -18,7 +17,6 @@ export async function CreatePost(formData: FormData) {
title: formData.get("title"),
description: formData.get("description"),
content: formData.get("content"),
category: formData.get("category"),
bannerImage: formData.get("bannerImage"),
});

Expand All @@ -28,7 +26,7 @@ export async function CreatePost(formData: FormData) {
};
}

const { title, description, content, category, bannerImage } = validation.data;
const { title, description, content, bannerImage } = validation.data;

await Prisma.post.create({
data: {
Expand All @@ -38,7 +36,6 @@ export async function CreatePost(formData: FormData) {
/<(input|hr|br|img)([^>]*?)>(?!<\/\1>)/gi,
"<$1$2/>"
),
category,
bannerImage,
slug: title
.toLowerCase()
Expand All @@ -64,7 +61,6 @@ export async function EditPost(formData: FormData) {
title: formData.get("title"),
description: formData.get("description"),
content: formData.get("content"),
category: formData.get("category"),
bannerImage: formData.get("bannerImage"),
});

Expand All @@ -74,7 +70,7 @@ export async function EditPost(formData: FormData) {
};
}

const { title, description, content, category, bannerImage } = validation.data;
const { title, description, content, bannerImage } = validation.data;

await Prisma.post.update({
where: { slug },
Expand All @@ -85,7 +81,6 @@ export async function EditPost(formData: FormData) {
/<(input|hr|br|img)([^>]*?)>(?!<\/\1>)/gi,
"<$1$2/>"
),
category,
bannerImage,
slug: title
.toLowerCase()
Expand Down
2 changes: 1 addition & 1 deletion src/app/(blog)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function BlogLayout({
return (
<>
<Navbar heading="Shiva Yadav" url="/" />
<main className="container flex-1">{children}</main>
<main className="mx-auto max-w-7xl flex-1">{children}</main>
<Footer />
</>
);
Expand Down
163 changes: 92 additions & 71 deletions src/app/(blog)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import { CategoryNav } from "@/components/CategoryNav";
import Link from "next/link";
import Prisma from "../../../prisma";
import { FormateDate } from "@/lib/FormateDate";
import { ArrowUpRight } from "lucide-react";
import Image from "next/image";
import { Heart, MessageCircle, CalendarDays } from "lucide-react";

export default async function Home({
searchParams,
}: {
searchParams: { category?: string };
}) {
export default async function Home() {
const blogs = await Prisma.post.findMany({
where: {
published: true,
...(searchParams.category && {
category: decodeURIComponent(searchParams.category),
}),
},
orderBy: {
createdAt: "desc",
Expand All @@ -27,78 +19,107 @@ export default async function Home({
});

return (
<div className="py-6">
{/* <CategoryNav /> */}

{blogs.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-8">
{blogs.map((post) => (
<Link
href={`/post/${post.slug}`}
key={post.slug}
className="group relative flex flex-col bg-card overflow-hidden rounded-xl border hover:shadow-lg transition-all duration-300"
>
{/* Image Container */}
<div className="aspect-[16/10] w-full relative overflow-hidden">
<Image
src={post.bannerImage || ""}
alt={post.title}
fill
className="object-cover transition-transform duration-300 group-hover:scale-105"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
<div className="mb-4 px-4 sm:px-6 lg:px-8">
{/* Featured Post (Latest) */}
{blogs.length > 0 && blogs[0].bannerImage && (
<section className="mb-16">
<Link
href={`/post/${blogs[0].slug}`}
className="group relative block overflow-hidden rounded-2xl"
>
<div className="relative aspect-[16/9]">
<Image
src={blogs[0].bannerImage}
alt={blogs[0].title}
fill
className="object-cover transition-transform duration-500 group-hover:scale-105"
priority
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/80 to-transparent" />
</div>
<div className="absolute bottom-0 w-full p-6 md:p-8">
<span className="mb-2 block text-sm">
{FormateDate(blogs[0].createdAt.toString())}
</span>
<h2 className="mb-2 line-clamp-1 text-2xl font-bold md:text-4xl">
{blogs[0].title}
</h2>
<p className="mb-2 line-clamp-1 max-w-2xl">
{blogs[0].description}
</p>
<div className="flex items-center gap-4">
<span className="flex items-center gap-1">
<Heart className="h-4 w-4" /> {blogs[0].likes.length}
</span>
<span className="flex items-center gap-1">
<MessageCircle className="h-4 w-4" />{" "}
{blogs[0].comments.length}
</span>
</div>
</div>
</Link>
</section>
)}

{/* Content Container */}
<div className="flex flex-col flex-1 p-6">
{/* Category and Date */}
<div className="flex items-center justify-between mb-4">
<span className="px-3 py-1 text-xs font-medium bg-primary/10 text-primary rounded-full">
{post.category}
</span>
<span className="text-sm text-muted-foreground">
{FormateDate(post.createdAt.toString())}
</span>
</div>

{/* Title and Description */}
<div className="flex-1">
<h2 className="text-xl font-bold mb-2 line-clamp-2 group-hover:text-primary transition-colors">
{post.title}
</h2>
<p className="text-muted-foreground line-clamp-2 mb-4">
{post.description}
</p>
</div>

{/* Footer - Interactions */}
<div className="flex items-center justify-between pt-4 border-t">
<div className="flex items-center gap-4 text-sm text-muted-foreground">
{/* Rest of the Posts */}
{blogs.length > 0 ? (
<section className="w-full space-y-4">
{blogs
.filter((post, index) => index !== 0 || !post.bannerImage)
.map((post) => (
<Link
href={`/post/${post.slug}`}
key={post.slug}
className="group flex h-[12rem] w-full justify-between rounded-lg border transition-all hover:shadow-md max-md:flex-col"
>
<div className="flex flex-col justify-between py-4 pl-6 pr-4">
<div className="flex flex-col gap-2">
<span className="flex items-center gap-1 text-sm text-muted-foreground">
<CalendarDays className="h-4 w-4" />{" "}
{FormateDate(post.createdAt.toString())}
</span>
<h2 className="line-clamp-2 text-2xl font-bold transition-colors group-hover:text-primary">
{post.title}
</h2>
<p className="line-clamp-1 text-muted-foreground">
{post.description}
</p>
</div>
<div className="flex items-center gap-4 text-muted-foreground">
<span className="flex items-center gap-1">
{post.likes.length}
<Heart className="h-4 w-4" /> {post.likes.length}
</span>
<span className="flex items-center gap-1">
💬 {post.comments.length}
<MessageCircle className="h-4 w-4" />{" "}
{post.comments.length}
</span>
</div>
<span className="text-sm font-medium text-primary flex items-center gap-1 group-hover:gap-2 transition-all">
Read more <ArrowUpRight className="w-4 h-4" />
</span>
</div>
</div>

{/* Hover Overlay */}
<div className="absolute inset-0 bg-primary/5 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" />
</Link>
))}
</div>
<div className="relative aspect-[16/9] max-w-[400px] max-md:max-w-full">
{post.bannerImage ? (
<Image
src={post.bannerImage}
alt={post.title}
fill
className="rounded-r-lg object-cover transition-transform duration-500 group-hover:scale-95"
/>
) : (
<div className="flex h-full w-full items-center justify-center bg-muted">
<span className="text-muted-foreground">
No Image Available
</span>
</div>
)}
</div>
</Link>
))}
</section>
) : (
<div className="flex flex-col items-center justify-center min-h-[50vh] text-center">
<h2 className="text-2xl font-bold text-foreground mb-2">No Posts Found</h2>
<div className="flex min-h-[40vh] flex-col items-center justify-center text-center">
<h2 className="mb-2 text-2xl font-bold">No Posts Found</h2>
<p className="text-muted-foreground">
{searchParams.category
? `No posts found in category "${decodeURIComponent(searchParams.category)}"`
: "No posts have been published yet"}
Check back later for new content!
</p>
</div>
)}
Expand Down
11 changes: 3 additions & 8 deletions src/app/(blog)/post/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,9 @@ const page = async ({ params }: { params: { slug: string } }) => {
<div className="relative mx-auto max-w-4xl py-6">
<div className="mb-6">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="text-sm text-muted-foreground">
{FormateDate(post.createdAt.toString())}
</span>
<span className="text-sm font-medium bg-primary/10 text-primary px-2 py-1 rounded-full">
{post.category}
</span>
</div>
<span className="text-sm text-muted-foreground">
{FormateDate(post.createdAt.toString())}
</span>
<LikeButton
postId={post.id}
isLiked={isLiked}
Expand Down
5 changes: 2 additions & 3 deletions src/app/(dashboard)/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Blogs from "@/components/Blogs";
import Blogs from "@/components/Blogs";
import Prisma from "../../../../prisma";

export default async function AdminPage() {
Expand All @@ -7,10 +7,9 @@ export default async function AdminPage() {
title: true,
slug: true,
createdAt: true,
category: true,
},
orderBy: {
createdAt: 'desc',
createdAt: "desc",
},
});

Expand Down
4 changes: 1 addition & 3 deletions src/components/Blogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ const Blogs = ({ posts }: { posts: any[] }) => {
<TableHeader>
<TableRow>
<TableHead>Title</TableHead>
<TableHead>Category</TableHead>
<TableHead>Published Date</TableHead>
<TableHead className="text-center">Edit</TableHead>
<TableHead className="text-center">Delete</TableHead>
Expand All @@ -68,10 +67,9 @@ const Blogs = ({ posts }: { posts: any[] }) => {
<TableBody>
{posts.map((post) => (
<TableRow key={post.slug}>
<TableCell className="line-clamp-2 w-full text-nowrap font-semibold ">
<TableCell className="line-clamp-2 w-full text-nowrap font-semibold">
{post.title.slice(0, 100)}
</TableCell>
<TableCell>{post.category}</TableCell>
<TableCell className="text-nowrap">
{FormateDate(post.createdAt.toString())}
</TableCell>
Expand Down
Loading

0 comments on commit f2914bb

Please sign in to comment.