From 5f527a4e4d75a5e3fb58e2748ac5f35a1c8f7ea4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:08:47 +0000 Subject: [PATCH 1/3] Initial plan From 1a5f26852d0f61f56de1b355564f7a7a315f8299 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Dec 2025 15:16:21 +0000 Subject: [PATCH 2/3] Add blog filtering by author and tags Co-authored-by: naoki-00-ito <117070296+naoki-00-ito@users.noreply.github.com> --- src/components/BlogCard.tsx | 38 +++++++++++++++----------- src/lib/getTags.ts | 11 ++++++++ src/pages/author/[name].astro | 50 +++++++++++++++++++++++++++++++++++ src/pages/tag/[tag].astro | 50 +++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 src/lib/getTags.ts create mode 100644 src/pages/author/[name].astro create mode 100644 src/pages/tag/[tag].astro diff --git a/src/components/BlogCard.tsx b/src/components/BlogCard.tsx index 3f97448..35a48e6 100644 --- a/src/components/BlogCard.tsx +++ b/src/components/BlogCard.tsx @@ -14,12 +14,14 @@ const BlogCard = ({ blog, color }: Props) => { return ( - - - {blog.data.title} - +
+ + + {blog.data.title} + +
- +
); }; diff --git a/src/lib/getTags.ts b/src/lib/getTags.ts new file mode 100644 index 0000000..41299e9 --- /dev/null +++ b/src/lib/getTags.ts @@ -0,0 +1,11 @@ +import { getCollection } from 'astro:content'; + +const getTags = async () => { + const blogs = await getCollection('blog'); + const allTags = blogs.flatMap(blog => blog.data.tags); + const uniqueTags = [...new Set(allTags)].sort(); + + return uniqueTags; +}; + +export default getTags; diff --git a/src/pages/author/[name].astro b/src/pages/author/[name].astro new file mode 100644 index 0000000..93c4437 --- /dev/null +++ b/src/pages/author/[name].astro @@ -0,0 +1,50 @@ +--- +import '@/styles/globals.css'; +import Layout from '@/layouts/Layout.astro'; +import PageTitle from '@/components/PageTitle.astro'; +import Section from '@/components/Section.astro'; +import BlogCard from '@/components/BlogCard'; +import Breadcrumb from '@/components/Breadcrumb.astro'; +import { getCollection } from 'astro:content'; +import member from '@/data/member'; + +export async function getStaticPaths() { + const authors = member.map(m => m.name); + + return authors.map(author => ({ + params: { name: author }, + })); +} + +const { name } = Astro.params; +const blogs = await getCollection('blog'); +const filteredBlogs = blogs + .filter(blog => blog.data.author === name) + .sort((a, b) => { + const dateA = new Date(a.data.pubDate).getTime(); + const dateB = new Date(b.data.pubDate).getTime(); + return dateB - dateA; + }); + +const title = `Blog - ${name}`; +const description = `${name}が執筆したBlogの一覧ページです。`; +--- + + + +
+ { + filteredBlogs.length > 0 ? ( +
+ {filteredBlogs.map(blog => ( + + ))} +
+ ) : ( +

記事がありません。

+ ) + } +
+ + +
diff --git a/src/pages/tag/[tag].astro b/src/pages/tag/[tag].astro new file mode 100644 index 0000000..565347f --- /dev/null +++ b/src/pages/tag/[tag].astro @@ -0,0 +1,50 @@ +--- +import '@/styles/globals.css'; +import Layout from '@/layouts/Layout.astro'; +import PageTitle from '@/components/PageTitle.astro'; +import Section from '@/components/Section.astro'; +import BlogCard from '@/components/BlogCard'; +import Breadcrumb from '@/components/Breadcrumb.astro'; +import { getCollection } from 'astro:content'; +import getTags from '@/lib/getTags'; + +export async function getStaticPaths() { + const tags = await getTags(); + + return tags.map(tag => ({ + params: { tag }, + })); +} + +const { tag } = Astro.params; +const blogs = await getCollection('blog'); +const filteredBlogs = blogs + .filter(blog => blog.data.tags.includes(tag)) + .sort((a, b) => { + const dateA = new Date(a.data.pubDate).getTime(); + const dateB = new Date(b.data.pubDate).getTime(); + return dateB - dateA; + }); + +const title = `Blog - #${tag}`; +const description = `#${tag}タグが付けられたBlogの一覧ページです。`; +--- + + + +
+ { + filteredBlogs.length > 0 ? ( +
+ {filteredBlogs.map(blog => ( + + ))} +
+ ) : ( +

記事がありません。

+ ) + } +
+ + +
From dba41cdc3cc004b3c6d084573de2b8f389b1530b Mon Sep 17 00:00:00 2001 From: Naoki_Ito <117070296+naoki-00-ito@users.noreply.github.com> Date: Tue, 9 Dec 2025 00:55:47 +0900 Subject: [PATCH 3/3] =?UTF-8?q?=F0=9F=90=9E=20fix:=20url=20path=20&=20filt?= =?UTF-8?q?er?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/BlogCard.tsx | 36 ++++++++++++++++-------- src/components/BlogFilter.astro | 30 ++++++++++++++++++++ src/lib/getTags.ts | 5 +++- src/pages/blog.astro | 2 ++ src/pages/{ => blog}/author/[name].astro | 2 ++ src/pages/{ => blog}/tag/[tag].astro | 13 +++++++-- 6 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 src/components/BlogFilter.astro rename src/pages/{ => blog}/author/[name].astro (95%) rename src/pages/{ => blog}/tag/[tag].astro (72%) diff --git a/src/components/BlogCard.tsx b/src/components/BlogCard.tsx index 35a48e6..ee7fbb1 100644 --- a/src/components/BlogCard.tsx +++ b/src/components/BlogCard.tsx @@ -3,6 +3,7 @@ import { Badge } from '@/components/ui/badge'; import member from '@/data/member'; import type { CollectionEntry } from 'astro:content'; import MemberIcon from '@/components/MemberIcon'; +import { cn } from '@/lib/utils'; type Props = { blog: CollectionEntry<'blog'>; @@ -13,15 +14,23 @@ const BlogCard = ({ blog, color }: Props) => { const author = member.find(m => m.name === blog.data.author); return ( - -
- - - {blog.data.title} - - + + +   + +
+ + {blog.data.title} +