Skip to content

Commit 51e0fc3

Browse files
committed
feat: add blogs
1 parent c548acb commit 51e0fc3

File tree

4 files changed

+189
-0
lines changed

4 files changed

+189
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"use client";
2+
3+
import { useState, useMemo } from "react";
4+
import BlogHeader from "@/components/blogs/BlogHeader";
5+
import { blogs, BlogTag } from "@/data/blogs";
6+
import Link from "next/link";
7+
8+
const filterTags: BlogTag[] = [
9+
"all",
10+
"engineering",
11+
"startup",
12+
"distribution",
13+
"misc",
14+
];
15+
16+
export default function BlogsPage() {
17+
const [selectedTag, setSelectedTag] = useState<BlogTag>("all");
18+
19+
const filteredBlogs = useMemo(() => {
20+
let result = blogs;
21+
if (selectedTag !== "all") {
22+
result = blogs.filter((blog) => blog.tag === selectedTag);
23+
}
24+
return result.sort((a, b) => {
25+
const parseDate = (dateStr: string) => {
26+
const [day, month, year] = dateStr.split("-").map(Number);
27+
return new Date(2000 + year, month - 1, day);
28+
};
29+
return parseDate(b.date).getTime() - parseDate(a.date).getTime();
30+
});
31+
}, [selectedTag]);
32+
33+
return (
34+
<main className="min-h-screen w-full bg-[#101010] text-white">
35+
<BlogHeader />
36+
<div className="max-w-[2000px] mx-auto px-6 py-8 flex justify-center">
37+
<div className="flex gap-12">
38+
{/* Sidebar with filters */}
39+
<aside className="w-48 flex-shrink-0">
40+
<nav className="flex flex-col gap-2">
41+
{filterTags.map((tag) => (
42+
<button
43+
key={tag}
44+
onClick={() => setSelectedTag(tag)}
45+
className={`text-left transition-colors lowercase ${
46+
selectedTag === tag
47+
? "text-white"
48+
: "text-[#9455f4] hover:text-white"
49+
}`}
50+
>
51+
{tag}
52+
</button>
53+
))}
54+
</nav>
55+
</aside>
56+
57+
{/* Blog list */}
58+
<div className="flex-1 max-w-2xl">
59+
<div className="flex flex-col gap-3">
60+
{filteredBlogs.length === 0 ? (
61+
<p className="text-gray-400">No blog posts found.</p>
62+
) : (
63+
filteredBlogs.map((blog, index) => (
64+
<div
65+
key={`${blog.date}-${blog.linkText}-${index}`}
66+
className="flex gap-4 items-center whitespace-nowrap"
67+
>
68+
<span className="text-white w-20 flex-shrink-0 font-DMfont font-mono text-right">
69+
{blog.date}
70+
</span>
71+
<Link
72+
href={blog.link}
73+
target="_blank"
74+
rel="noopener noreferrer"
75+
className="text-[#9455f4] hover:text-white underline transition-colors"
76+
>
77+
{blog.linkText}
78+
</Link>
79+
</div>
80+
))
81+
)}
82+
</div>
83+
</div>
84+
</div>
85+
</div>
86+
</main>
87+
);
88+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
"use client";
2+
3+
import Link from "next/link";
4+
5+
export default function BlogHeader() {
6+
return (
7+
<header className="w-full border-b border-[#252525] bg-[#101010]">
8+
<div className="max-w-[2000px] mx-auto px-6 py-4 flex items-center justify-between">
9+
<Link
10+
href="/blogs"
11+
className="text-white hover:text-[#9455f4] transition-colors underline"
12+
>
13+
Opensox AI (Ajeet)
14+
</Link>
15+
<Link
16+
href="/"
17+
className="text-white hover:text-[#9455f4] transition-colors underline"
18+
>
19+
Home
20+
</Link>
21+
</div>
22+
</header>
23+
);
24+
}
25+

apps/web/src/components/landing-sections/footer.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ const Footer = () => {
6565
>
6666
Pricing
6767
</Link>
68+
<Link
69+
href="/blogs"
70+
className="text-[#b1b1b1] hover:text-white transition-colors text-xs"
71+
>
72+
Blogs
73+
</Link>
6874
{/* <Link
6975
href="#"
7076
className="text-[#b1b1b1] hover:text-white transition-colors text-xs"

apps/web/src/data/blogs.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
export type BlogTag =
2+
| "engineering"
3+
| "startup"
4+
| "distribution"
5+
| "misc"
6+
| "all";
7+
8+
export interface BlogPost {
9+
date: string;
10+
linkText: string;
11+
link: string;
12+
tag: BlogTag;
13+
}
14+
15+
export const blogs: BlogPost[] = [
16+
{
17+
date: "24-08-25",
18+
linkText: "how to build an online presense?",
19+
link: "https://x.com/ajeetunc/status/1959480811293708369?s=20",
20+
tag: "distribution",
21+
},
22+
{
23+
date: "30-07-24",
24+
linkText: "how to get into gsoc (part-2)",
25+
link: "https://x.com/ajeetunc/status/1818130583509156163?s=20",
26+
tag: "misc",
27+
},
28+
{
29+
date: "29-07-24",
30+
linkText: "how to get into gsoc (part-1)",
31+
link: "https://x.com/ajeetunc/status/1817760248599634314?s=20",
32+
tag: "misc",
33+
},
34+
{
35+
date: "02-08-24",
36+
linkText: "how to get into gsoc (part-3)",
37+
link: "https://x.com/ajeetunc/status/1819209955330666623?s=20",
38+
tag: "misc",
39+
},
40+
{
41+
date: "02-12-23",
42+
linkText: "why you should do open source?",
43+
link: "https://x.com/ajeetunc/status/1987490955298230369?s=20",
44+
tag: "engineering",
45+
},
46+
{
47+
date: "10-11-25",
48+
linkText: "ugly execution wins",
49+
link: "https://x.com/ajeetunc/status/1987931607102341182?s=20",
50+
tag: "misc",
51+
},
52+
{
53+
date: "08-11-25",
54+
linkText: "why you shouln't register a company?",
55+
link: "https://x.com/ajeetunc/status/1987125877985968217?s=20",
56+
tag: "startup",
57+
},
58+
{
59+
date: "08-11-25",
60+
linkText: "tiny habits that changed my life",
61+
link: "https://x.com/ajeetunc/status/1987043154974154762?s=20",
62+
tag: "misc",
63+
},
64+
{
65+
date: "29-10-25",
66+
linkText: "how to be layoff proof?",
67+
link: "https://x.com/ajeetunc/status/1983389367327699032?s=20",
68+
tag: "misc",
69+
},
70+
];

0 commit comments

Comments
 (0)