added dates in the site

This commit is contained in:
Cypro Freelance 2024-08-20 19:58:54 +05:30
parent 7a27e2b79e
commit 5bf1589b7a
5 changed files with 86 additions and 59 deletions

View file

@ -4,16 +4,18 @@ import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { ArrowLeft } from "lucide-react"; import { ArrowLeft } from "lucide-react";
import { Separator } from "@/components/ui/separator"; import { Separator } from "@/components/ui/separator";
import NotFound from "@/app/not-found"; import { notFound } from "next/navigation";
import { Metadata } from "next"; import { Metadata } from "next";
import { format } from "date-fns";
async function getData(slug: string) { async function getData(slug: string) {
const query = ` const query = `
*[_type == "blog" && slug.current == '${slug}'] { *[_type == "blog" && slug.current == '${slug}'] {
"currentSlug": slug.current, "currentSlug": slug.current,
title, title,
content, content,
titleImage titleImage,
_createdAt
}[0]`; }[0]`;
const data = await client.fetch(query); const data = await client.fetch(query);
@ -25,6 +27,7 @@ interface BlogSlugArticle {
title: string; title: string;
content: any; content: any;
titleImage: string; titleImage: string;
_createdAt: string;
} }
export async function generateMetadata({ export async function generateMetadata({
@ -77,9 +80,11 @@ export default async function BlogSlugArticle({
const data: BlogSlugArticle = await getData(params.slug); const data: BlogSlugArticle = await getData(params.slug);
if (!data) { if (!data) {
return <NotFound />; notFound();
} }
const formattedDate = format(new Date(data._createdAt), "MMMM d, yyyy");
return ( return (
<> <>
<section className="max-w-5xl container mx-auto py-8 md:py-28 flex flex-col items-center px-4"> <section className="max-w-5xl container mx-auto py-8 md:py-28 flex flex-col items-center px-4">
@ -90,10 +95,10 @@ export default async function BlogSlugArticle({
<ArrowLeft className="mr-2" /> <ArrowLeft className="mr-2" />
Back to Blog Back to Blog
</Link> </Link>
<header className="text-start mb-12 w-full"> <header className="text-start mb-8 w-full">
{data.titleImage && ( {data.titleImage && (
<div className="mb-8"> <div className="mb-2">
<h1 className="text-3xl md:text-5xl mb-12 font-bold text-black dark:bg-clip-text dark:text-transparent dark:bg-gradient-to-b dark:from-white dark:to-neutral-400"> <h1 className="text-3xl md:text-5xl mb-12 py-4 font-bold text-black dark:bg-clip-text dark:text-transparent dark:bg-gradient-to-b dark:from-white dark:to-neutral-400">
{data.title} {data.title}
</h1> </h1>
<Image <Image
@ -104,6 +109,9 @@ export default async function BlogSlugArticle({
priority priority
className="w-full h-auto object-cover rounded-md" className="w-full h-auto object-cover rounded-md"
/> />
<p className="mt-4 text-xl text-muted-foreground">
Uploaded at {formattedDate}
</p>{" "}
</div> </div>
)} )}
</header> </header>

19
app/(root)/not-found.tsx Normal file
View file

@ -0,0 +1,19 @@
import Link from "next/link";
const NotFound = () => {
return (
<section id="404error" className="flex-center flex-col wrapper container">
<h1 className="text-3xl md:text-5xl text-center">
<span className="text-red-500">404</span> Page not Found
</h1>
<p className="text-lg mt-3 text-muted-foreground">
Please return back to{" "}
<Link href="/" className="underline font-bold">
Home
</Link>
</p>
</section>
);
};
export default NotFound;

View file

@ -1,19 +0,0 @@
import Link from "next/link";
const NotFound = () => {
return (
<section id="404error" className="flex-center flex-col wrapper container">
<h1 className="text-3xl md:text-5xl text-center">
<span className="text-red-500">404</span> Page not Found
</h1>
<p className="text-lg mt-3 text-muted-foreground">
Please return back to{" "}
<Link href="/" className="underline font-bold">
Home
</Link>
</p>
</section>
);
};
export default NotFound;

View file

@ -12,12 +12,14 @@ import {
PaginationNext, PaginationNext,
PaginationPrevious, PaginationPrevious,
} from "@/components/ui/pagination"; } from "@/components/ui/pagination";
import { format } from "date-fns";
interface BlogPostcard { interface BlogPostcard {
title: string; title: string;
smallDescription: string; smallDescription: string;
currentSlug: string; currentSlug: string;
titleImage: string; titleImage: string;
_createdAt: string; // Add createdAt field
} }
interface BlogCardsProps { interface BlogCardsProps {
@ -33,7 +35,8 @@ const BlogCards: React.FC<BlogCardsProps> = async ({ searchParams }) => {
title, title,
smallDescription, smallDescription,
"currentSlug": slug.current, "currentSlug": slug.current,
titleImage titleImage,
_createdAt
}[${(currentPage - 1) * cardsPerPage}...${currentPage * cardsPerPage}]`; }[${(currentPage - 1) * cardsPerPage}...${currentPage * cardsPerPage}]`;
const posts: BlogPostcard[] = await client.fetch(query); const posts: BlogPostcard[] = await client.fetch(query);
@ -47,38 +50,49 @@ const BlogCards: React.FC<BlogCardsProps> = async ({ searchParams }) => {
return ( return (
<> <>
<section className="grid max-w-6xl gap-4 mx-auto sm:grid-cols-2 lg:grid-cols-3"> <section className="grid max-w-6xl gap-4 mx-auto sm:grid-cols-2 lg:grid-cols-3">
{posts.map((post, idx) => ( {posts.map((post, idx) => {
<Card const formattedDate = format(
className="group h-full w-full rounded-lg border overflow-hidden" new Date(post._createdAt),
key={idx} "MMMM d, yyyy"
> ); // Format the date
<Link href={`/blog/${post.currentSlug}`} className="block">
<div className="relative overflow-hidden rounded-t-lg"> return (
<Image <Card
src={urlFor(post.titleImage).url()} className="group h-full w-full rounded-lg border overflow-hidden"
alt={post.title} key={idx}
width={500} >
height={300} <Link href={`/blog/${post.currentSlug}`} className="block">
priority <div className="relative overflow-hidden rounded-t-lg">
className="w-full object-cover transition-transform duration-200 group-hover:scale-105" <Image
/> src={urlFor(post.titleImage).url()}
</div> alt={post.title}
<CardContent className="p-4"> width={500}
<div className="flex-between mb-2 py-2"> height={300}
<h3 className="text-xl font-semibold leading-tight"> priority
{post.title} className="w-full object-cover transition-transform duration-200 group-hover:scale-105"
</h3> />
<div className="text-sm text-muted-foreground opacity-0 group-hover:opacity-100 duration-300">
<ExternalLink />
</div>
</div> </div>
<p className="text-sm text-muted-foreground"> <CardContent className="p-4">
{post.smallDescription} <div className="flex-between mb-2 py-2">
</p> <h3 className="text-xl font-semibold leading-tight">
</CardContent> {post.title}
</Link> </h3>
</Card> <div className="text-sm text-muted-foreground opacity-0 group-hover:opacity-100 duration-300">
))} <ExternalLink />
</div>
</div>
<p className="text-sm text-muted-foreground">
{post.smallDescription}
</p>
<p className="text-xs text-muted-foreground mt-2">
Published on: {formattedDate}{" "}
{/* Display the formatted date */}
</p>
</CardContent>
</Link>
</Card>
);
})}
</section> </section>
<div className="flex-center mt-12"> <div className="flex-center mt-12">
{totalPages > 1 && ( {totalPages > 1 && (

View file

@ -21,6 +21,11 @@ export default {
type: 'image', type: 'image',
title: 'Title Image', title: 'Title Image',
}, },
// {
// name: 'publishedAt',
// title: 'Published At',
// type: 'datetime',
// },
{ {
name: 'smallDescription', name: 'smallDescription',
type: 'text', type: 'text',