Skip to content

Commit b1685fb

Browse files
authored
Merge pull request #240 from 1chooo/feature/#239
Feature/#239
2 parents 4b643f1 + 48f9851 commit b1685fb

File tree

5 files changed

+112
-116
lines changed

5 files changed

+112
-116
lines changed

apps/web/src/app/blog/page.tsx

+55-44
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,73 @@ import Link from 'next/link';
22
import { getBlogPosts } from '@/app/db/blog';
33
import PageHeader from '@/components/page-header';
44
import Image from 'next/image';
5+
import FilterSelectBox from '@/components/blog/filter-select-box';
6+
import FilterList from '@/components/blog/filter-list';
57

68
export const metadata = {
79
title: 'Blog | Hugo ChunHo Lin (1chooo) | Open Source Enthusiast',
810
description: 'Read my thoughts on software development, design, and more.',
911
};
1012

11-
export default function BlogPage() {
13+
let blogTags: string[] = ['All'];
14+
15+
export default function BlogPage({ searchParams }: { searchParams: { tag?: string } }) {
1216
let allBlogs = getBlogPosts();
17+
blogTags = ['All', ...Array.from(new Set(allBlogs.map(post => post.metadata.category ?? '')))];
18+
const selectedTag = searchParams.tag || 'All';
19+
20+
// Filter blogs based on the selected tag
21+
const filteredBlogs = selectedTag === 'All'
22+
? allBlogs
23+
: allBlogs.filter(post => post.metadata.category === selectedTag);
1324

1425
return (
1526
<article>
1627
<PageHeader title="Hugo's Blog" />
17-
<ul className="blog-posts-list">
18-
{allBlogs
19-
.sort((a, b) => {
20-
if (
21-
new Date(a.metadata.publishedAt) > new Date(b.metadata.publishedAt)
22-
) {
23-
return -1;
24-
}
25-
return 1;
26-
})
27-
.map((post, index) => (
28-
<li
29-
key={index}
30-
className="blog-post-item active"
31-
data-category={post.metadata.category}
32-
>
33-
<Link
34-
href={`/blog/${post.slug}`}
35-
rel="noopener noreferrer"
28+
<section className="blog-posts">
29+
<FilterList selectedTag={selectedTag} blogTags={blogTags} />
30+
<FilterSelectBox selectedTag={selectedTag} blogTags={blogTags} />
31+
32+
<ul className="blog-posts-list">
33+
{filteredBlogs
34+
.sort((a, b) => {
35+
if (new Date(a.metadata.publishedAt) > new Date(b.metadata.publishedAt)) {
36+
return -1;
37+
}
38+
return 1;
39+
})
40+
.map((post, index) => (
41+
<li
42+
key={index}
43+
className="blog-post-item active"
44+
data-category={post.metadata.category}
3645
>
37-
<figure className="blog-banner-box">
38-
<Image
39-
src={post.metadata.banner}
40-
alt={post.metadata.alt || 'Blog post image'}
41-
loading="lazy"
42-
width={1600}
43-
height={900}
44-
/>
45-
</figure>
46-
<div className="blog-content">
47-
<div className="blog-meta">
48-
<p className="blog-category">{post.metadata.category}</p>
49-
<span className="dot"></span>
50-
<time dateTime={post.metadata.publishedAt}>
51-
{new Date(post.metadata.publishedAt).toLocaleDateString()}
52-
</time>
46+
<Link href={`/blog/${post.slug}`} rel="noopener noreferrer">
47+
<figure className="blog-banner-box">
48+
<Image
49+
src={post.metadata.banner}
50+
alt={post.metadata.alt || 'Blog post image'}
51+
loading="lazy"
52+
width={1600}
53+
height={900}
54+
/>
55+
</figure>
56+
<div className="blog-content">
57+
<div className="blog-meta">
58+
<p className="blog-category">{post.metadata.category}</p>
59+
<span className="dot"></span>
60+
<time dateTime={post.metadata.publishedAt}>
61+
{new Date(post.metadata.publishedAt).toLocaleDateString()}
62+
</time>
63+
</div>
64+
<h3 className="h3 blog-item-title">{post.metadata.title}</h3>
65+
<p className="blog-text">{post.metadata.summary}</p>
5366
</div>
54-
<h3 className="h3 blog-item-title">{post.metadata.title}</h3>
55-
<p className="blog-text">{post.metadata.summary}</p>
56-
</div>
57-
</Link>
58-
</li>
59-
))}
60-
</ul>
61-
</article >
67+
</Link>
68+
</li>
69+
))}
70+
</ul>
71+
</section>
72+
</article>
6273
);
6374
}

apps/web/src/app/globals.css

+27
Original file line numberDiff line numberDiff line change
@@ -1049,9 +1049,23 @@ main {
10491049
border-radius: 8px;
10501050
}
10511051

1052+
.select-item button a {
1053+
background: var(--eerie-black-2);
1054+
color: var(--light-gray);
1055+
font-size: var(--fs-6);
1056+
font-weight: var(--fw-300);
1057+
text-transform: capitalize;
1058+
width: 100%;
1059+
padding: 8px 10px;
1060+
border-radius: 8px;
1061+
}
1062+
10521063
.select-item button:hover {
10531064
--eerie-black-2: hsl(240, 2%, 20%);
10541065
}
1066+
.select-item button a:hover {
1067+
--eerie-black-2: hsl(240, 2%, 20%);
1068+
}
10551069

10561070
.project-list {
10571071
display: grid;
@@ -1831,13 +1845,26 @@ textarea.form-input::-webkit-resizer {
18311845
transition: var(--transition-1);
18321846
}
18331847

1848+
.filter-item a {
1849+
color: var(--light-gray);
1850+
font-size: var(--fs-5);
1851+
transition: var(--transition-1);
1852+
}
1853+
18341854
.filter-item button:hover {
18351855
color: var(--light-gray-70);
18361856
}
18371857

18381858
.filter-item button.active {
18391859
color: var(--orange-yellow-crayola);
18401860
}
1861+
.filter-item a:hover {
1862+
color: var(--light-gray-70);
1863+
}
1864+
1865+
.filter-item a.active {
1866+
color: var(--orange-yellow-crayola);
1867+
}
18411868

18421869
/* portfolio and blog grid */
18431870

apps/web/src/components/blog/filter-list.tsx

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
import React from 'react';
2-
import { blogTags } from '@/config/blog';
3-
import { handleBlogPaginationFilter } from '@/lib/utils/filter-utils';
4-
2+
import Link from 'next/link';
53

64
interface FilterListProps {
7-
selectedValue: string;
8-
setSelectedValue: React.Dispatch<React.SetStateAction<string>>;
9-
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
5+
selectedTag: string;
6+
blogTags: string[];
107
}
118

12-
const FilterList: React.FC<FilterListProps> = ({ selectedValue, setSelectedValue, setCurrentPage }) => {
9+
const FilterList: React.FC<FilterListProps> = ({
10+
selectedTag,
11+
blogTags
12+
}) => {
1313

1414
return (
1515
<ul className="filter-list">
1616
{blogTags.map((tag, index) => (
1717
<li className="filter-item" key={index}>
18-
<button
19-
className={`filter-btn ${selectedValue === tag ? 'active' : ''}`}
20-
onClick={() => handleBlogPaginationFilter(tag, setSelectedValue, setCurrentPage)}
18+
<Link
19+
href={`/blog?tag=${encodeURIComponent(tag || '')}`}
20+
className={`filter-btn ${selectedTag === tag ? 'active' : ''}`}
2121
>
2222
{tag}
23-
</button>
23+
</Link>
2424
</li>
2525
))}
2626
</ul>
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
1-
import React from 'react';
1+
"use client";
2+
3+
import React, { useState } from 'react';
24
import { MdExpandMore } from 'react-icons/md';
3-
import { blogTags } from '@/config/blog';
4-
import { handleBlogPaginationFilter } from '@/lib/utils/filter-utils';
5+
import Link from 'next/link';
56

67
interface FilterSelectBoxProps {
7-
selectedValue: string;
8-
setSelectedValue: React.Dispatch<React.SetStateAction<string>>;
9-
isSelectActive: boolean;
10-
setIsSelectActive: React.Dispatch<React.SetStateAction<boolean>>;
11-
setCurrentPage: React.Dispatch<React.SetStateAction<number>>;
8+
selectedTag: string;
9+
blogTags: string[];
1210
}
1311

1412
const FilterSelectBox: React.FC<FilterSelectBoxProps> = ({
15-
selectedValue,
16-
setSelectedValue,
17-
isSelectActive,
18-
setIsSelectActive,
19-
setCurrentPage
13+
selectedTag,
14+
blogTags
2015
}) => {
16+
const [isSelectActive, setIsSelectActive] = useState(false);
2117

2218
return (
2319
<div className="filter-select-box">
@@ -26,7 +22,7 @@ const FilterSelectBox: React.FC<FilterSelectBoxProps> = ({
2622
onClick={() => setIsSelectActive(!isSelectActive)}
2723
>
2824
<div className="select-value">
29-
{selectedValue || 'Select category'}
25+
{selectedTag || 'Select category'}
3026
</div>
3127
<div className="select-icon">
3228
<MdExpandMore />
@@ -36,8 +32,14 @@ const FilterSelectBox: React.FC<FilterSelectBoxProps> = ({
3632
<ul className="select-list">
3733
{blogTags.map((tag: string) => (
3834
<li className="select-item" key={tag}>
39-
<button onClick={() => handleBlogPaginationFilter(tag, setSelectedValue, setCurrentPage)}>
40-
{tag}
35+
<button
36+
onClick={() => {
37+
setIsSelectActive(false);
38+
}}
39+
>
40+
<Link href={`/blog?tag=${encodeURIComponent(tag || '')}`}>
41+
{tag}
42+
</Link>
4143
</button>
4244
</li>
4345
))}
@@ -47,4 +49,4 @@ const FilterSelectBox: React.FC<FilterSelectBoxProps> = ({
4749
);
4850
};
4951

50-
export default FilterSelectBox;
52+
export default FilterSelectBox;

apps/web/src/contents/example.mdx

-44
This file was deleted.

0 commit comments

Comments
 (0)