Skip to content

Commit e8cd3e8

Browse files
committed
2 parents 33dc3fd + eb1af1e commit e8cd3e8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3704
-234
lines changed

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npm run build

README.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,18 @@ Light Hooks is a collection of carefully crafted React hooks designed to:
3232

3333
Visit the [npm package](https://www.npmjs.com/package/light-hooks) to get started with the hooks.
3434

35-
## Learn More
35+
## Documentation Resources
3636

37-
To learn more about Next.js, take a look at the following resources:
37+
To learn more about the technologies used in this documentation site:
3838

39-
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
40-
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
39+
- [Next.js Documentation](https://nextjs.org/docs) - Learn about Next.js features and API
40+
- [Light Hooks GitHub](https://github.com/Gourav2609/light-hooks) - Main hooks library repository
41+
- [Light Hooks npm Package](https://www.npmjs.com/package/light-hooks) - Install and use the hooks
4142

42-
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
43+
## Contributing
4344

44-
## Deploy on Vercel
45+
We welcome contributions to both the hooks library and documentation! Check out our [Contributing Guide](/docs/contributing) for more information.
4546

46-
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
47+
## Deployment
4748

48-
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
49+
This documentation site is deployed on [Vercel](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) and includes analytics to help us improve the documentation experience.

app/blog/page.tsx

Lines changed: 175 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,195 @@
1-
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
2-
import {
3-
Author,
4-
BlogMdxFrontmatter,
5-
getAllBlogsFrontmatter,
6-
} from "@/lib/markdown";
7-
import { formatDate2, stringToDate } from "@/lib/utils";
1+
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
2+
import { Badge } from "@/components/ui/badge";
3+
import { ExternalLink, Calendar, Clock, ArrowRight } from "lucide-react";
84
import { Metadata } from "next";
9-
import Image from "next/image";
105
import Link from "next/link";
6+
import { getLocalPosts, getExternalPosts, BlogPost, Author } from "@/data/blog-posts";
117

128
export const metadata: Metadata = {
13-
title: "AriaDocs - Blog",
9+
title: "Light Hooks - Blog",
10+
description: "Latest articles, tutorials, and insights about React hooks development and best practices.",
1411
};
1512

16-
export default async function BlogIndexPage() {
17-
const blogs = (await getAllBlogsFrontmatter()).sort(
18-
(a, b) => stringToDate(b.date).getTime() - stringToDate(a.date).getTime()
19-
);
13+
export default function BlogPage() {
14+
const localPosts = getLocalPosts();
15+
const externalPosts = getExternalPosts();
16+
2017
return (
21-
<div className="flex flex-col gap-1 sm:min-h-[91vh] min-h-[88vh] pt-2">
22-
<div className="mb-7 flex flex-col gap-2">
23-
<h1 className="sm:text-3xl text-2xl font-extrabold">
24-
The latest blogs of this product
18+
<div className="container mx-auto px-4 py-8 max-w-7xl">
19+
{/* Header */}
20+
<div className="mb-12 text-center">
21+
<h1 className="text-4xl md:text-5xl font-bold mb-4 bg-gradient-to-r from-primary via-blue-600 to-purple-600 bg-clip-text text-transparent">
22+
Blog & Articles
2523
</h1>
26-
<p className="text-muted-foreground sm:text-[16.5px] text-[14.5px]">
27-
All the latest blogs and news, straight from the team.
24+
<p className="text-lg text-muted-foreground max-w-2xl mx-auto">
25+
Insights, tutorials, and thoughts on React development, custom hooks, and modern web development practices.
2826
</p>
2927
</div>
30-
<div className="grid md:grid-cols-3 sm:grid-cols-2 grid-cols-1 sm:gap-8 gap-4 mb-5">
31-
{blogs.map((blog) => (
32-
<BlogCard {...blog} slug={blog.slug} key={blog.slug} />
33-
))}
34-
</div>
28+
29+
{/* Featured/Recent Posts */}
30+
{localPosts.length > 0 && (
31+
<section className="mb-16">
32+
<div className="flex items-center gap-3 mb-8">
33+
<h2 className="text-2xl font-bold">Latest Articles</h2>
34+
<Badge variant="secondary" className="bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-300">
35+
On Site
36+
</Badge>
37+
</div>
38+
39+
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
40+
{localPosts.map((post) => (
41+
<BlogCard key={post.id} post={post} />
42+
))}
43+
</div>
44+
</section>
45+
)}
46+
47+
{/* External Posts */}
48+
{externalPosts.length > 0 && (
49+
<section>
50+
<div className="flex items-center gap-3 mb-8">
51+
<h2 className="text-2xl font-bold">Published Elsewhere</h2>
52+
<Badge variant="outline" className="border-blue-200 text-blue-700 dark:border-blue-800 dark:text-blue-300">
53+
External
54+
</Badge>
55+
</div>
56+
57+
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
58+
{externalPosts.map((post) => (
59+
<ExternalBlogCard key={post.id} post={post} />
60+
))}
61+
</div>
62+
</section>
63+
)}
3564
</div>
3665
);
3766
}
3867

39-
function BlogCard({
40-
date,
41-
title,
42-
description,
43-
slug,
44-
cover,
45-
authors,
46-
}: BlogMdxFrontmatter & { slug: string }) {
68+
function BlogCard({ post }: { post: BlogPost }) {
4769
return (
4870
<Link
49-
href={`/blog/${slug}`}
50-
className="flex flex-col gap-2 items-start border rounded-md py-5 px-3 min-h-[400px]"
71+
href={`/blog/${post.slug}`}
72+
className="group block bg-card border rounded-lg overflow-hidden hover:shadow-lg transition-all duration-300 hover:-translate-y-1"
5173
>
52-
<h3 className="text-md font-semibold -mt-1 pr-7">{title}</h3>
53-
<div className="w-full">
54-
<Image
55-
src={cover}
56-
alt={title}
57-
width={400}
58-
height={150}
59-
quality={80}
60-
className="w-full rounded-md object-cover h-[180px] border"
61-
/>
74+
<div className="aspect-video relative overflow-hidden">
75+
<div className="w-full h-full bg-gradient-to-br from-blue-500/20 to-purple-500/20 flex items-center justify-center">
76+
<span className="text-4xl font-bold text-muted-foreground/50">
77+
{post.title.charAt(0)}
78+
</span>
79+
</div>
6280
</div>
63-
<p className="text-sm text-muted-foreground">{description}</p>
64-
<div className="flex items-center justify-between w-full mt-auto">
65-
<p className="text-[13px] text-muted-foreground">
66-
Published on {formatDate2(date)}
81+
82+
<div className="p-6">
83+
<div className="flex items-center gap-2 mb-3">
84+
{post.tags.slice(0, 2).map((tag: string) => (
85+
<Badge key={tag} variant="secondary" className="text-xs">
86+
{tag}
87+
</Badge>
88+
))}
89+
</div>
90+
91+
<h3 className="font-semibold text-lg mb-2 group-hover:text-primary transition-colors line-clamp-2">
92+
{post.title}
93+
</h3>
94+
95+
<p className="text-sm text-muted-foreground mb-4 line-clamp-2">
96+
{post.description}
6797
</p>
68-
<AvatarGroup users={authors} />
98+
99+
<div className="flex items-center justify-between text-sm text-muted-foreground">
100+
<div className="flex items-center gap-4">
101+
<div className="flex items-center gap-1">
102+
<Calendar className="w-4 h-4" />
103+
{new Date(post.date).toLocaleDateString()}
104+
</div>
105+
<div className="flex items-center gap-1">
106+
<Clock className="w-4 h-4" />
107+
{post.readTime}
108+
</div>
109+
</div>
110+
111+
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
112+
</div>
113+
114+
<div className="flex items-center gap-2 mt-4 pt-4 border-t">
115+
<AvatarGroup users={post.authors} />
116+
</div>
69117
</div>
70118
</Link>
71119
);
72120
}
73121

74-
function AvatarGroup({ users, max = 4 }: { users: Author[]; max?: number }) {
122+
function ExternalBlogCard({ post }: { post: BlogPost }) {
123+
const platformColors = {
124+
Medium: "bg-gray-800 text-white",
125+
LinkedIn: "bg-blue-600 text-white",
126+
"Dev.to": "bg-black text-white"
127+
};
128+
129+
return (
130+
<a
131+
href={post.externalUrl}
132+
target="_blank"
133+
rel="noopener noreferrer"
134+
className="group block bg-card border rounded-lg overflow-hidden hover:shadow-lg transition-all duration-300 hover:-translate-y-1 relative"
135+
>
136+
{/* External indicator */}
137+
<div className="absolute top-3 right-3 z-10">
138+
<div className={`px-2 py-1 rounded-md text-xs font-medium flex items-center gap-1 ${platformColors[post.platform as keyof typeof platformColors] || 'bg-gray-600 text-white'}`}>
139+
<ExternalLink className="w-3 h-3" />
140+
{post.platform}
141+
</div>
142+
</div>
143+
144+
<div className="aspect-video relative overflow-hidden">
145+
<div className="w-full h-full bg-gradient-to-br from-purple-500/20 to-pink-500/20 flex items-center justify-center">
146+
<span className="text-4xl font-bold text-muted-foreground/50">
147+
{post.title.charAt(0)}
148+
</span>
149+
</div>
150+
</div>
151+
152+
<div className="p-6">
153+
<div className="flex items-center gap-2 mb-3">
154+
{post.tags.slice(0, 2).map((tag: string) => (
155+
<Badge key={tag} variant="outline" className="text-xs">
156+
{tag}
157+
</Badge>
158+
))}
159+
</div>
160+
161+
<h3 className="font-semibold text-lg mb-2 group-hover:text-primary transition-colors line-clamp-2">
162+
{post.title}
163+
</h3>
164+
165+
<p className="text-sm text-muted-foreground mb-4 line-clamp-2">
166+
{post.description}
167+
</p>
168+
169+
<div className="flex items-center justify-between text-sm text-muted-foreground">
170+
<div className="flex items-center gap-4">
171+
<div className="flex items-center gap-1">
172+
<Calendar className="w-4 h-4" />
173+
{new Date(post.date).toLocaleDateString()}
174+
</div>
175+
<div className="flex items-center gap-1">
176+
<Clock className="w-4 h-4" />
177+
{post.readTime}
178+
</div>
179+
</div>
180+
181+
<ExternalLink className="w-4 h-4 group-hover:scale-110 transition-transform" />
182+
</div>
183+
184+
<div className="flex items-center gap-2 mt-4 pt-4 border-t">
185+
<AvatarGroup users={post.authors} />
186+
</div>
187+
</div>
188+
</a>
189+
);
190+
}
191+
192+
function AvatarGroup({ users, max = 3 }: { users: Author[]; max?: number }) {
75193
const displayUsers = users.slice(0, max);
76194
const remainingUsers = Math.max(users.length - max, 0);
77195

@@ -80,19 +198,18 @@ function AvatarGroup({ users, max = 4 }: { users: Author[]; max?: number }) {
80198
{displayUsers.map((user, index) => (
81199
<Avatar
82200
key={user.username}
83-
className={`inline-block border-2 w-9 h-9 border-background ${
84-
index !== 0 ? "-ml-3" : ""
85-
} `}
201+
className={`inline-block border-2 border-background w-8 h-8 ${
202+
index !== 0 ? "-ml-2" : ""
203+
}`}
86204
>
87-
<AvatarImage src={user.avatar} alt={user.username} />
88-
<AvatarFallback>
89-
{user.username.slice(0, 2).toUpperCase()}
205+
<AvatarFallback className="text-xs">
206+
{user.name.split(' ').map((n: string) => n[0]).join('').toUpperCase()}
90207
</AvatarFallback>
91208
</Avatar>
92209
))}
93210
{remainingUsers > 0 && (
94-
<Avatar className="-ml-3 inline-block border-2 border-background hover:translate-y-1 transition-transform">
95-
<AvatarFallback>+{remainingUsers}</AvatarFallback>
211+
<Avatar className="-ml-2 inline-block border-2 border-background w-8 h-8">
212+
<AvatarFallback className="text-xs">+{remainingUsers}</AvatarFallback>
96213
</Avatar>
97214
)}
98215
</div>

app/docs/layout.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
import { Leftbar } from "@/components/leftbar";
2+
import { Metadata } from "next";
3+
4+
export const metadata: Metadata = {
5+
title: {
6+
template: "%s | Light Hooks Documentation",
7+
default: "Documentation | Light Hooks"
8+
},
9+
description: "Comprehensive documentation for Light Hooks - A collection of useful React hooks for modern web development.",
10+
robots: {
11+
index: true,
12+
follow: true,
13+
googleBot: {
14+
index: true,
15+
follow: true,
16+
'max-video-preview': -1,
17+
'max-image-preview': 'large',
18+
'max-snippet': -1,
19+
},
20+
},
21+
};
222

323
export default function DocsLayout({
424
children,

0 commit comments

Comments
 (0)