Skip to content

Commit

Permalink
impl tag filter ui
Browse files Browse the repository at this point in the history
  • Loading branch information
kzhrk committed May 15, 2024
1 parent ecbcfff commit a7c2c3e
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 18 deletions.
48 changes: 31 additions & 17 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
<script lang="ts" setup>
import { format } from "date-fns";
const route = useRoute();
const router = useRouter();
const { data: allPosts } = await useFetch("/api/posts");
const { data: allTags } = await useFetch("/api/tags");
const tag = computed(() => route.query.tag);
const tags = computed(() =>
useRoute().query.tags ? [useRoute().query.tags].flat() : [],
const tagOptions = computed(
(): { label: string; value: string; selected: boolean }[] =>
[undefined, ...allTags.value].map((t) => ({
label: t || "未選択",
value: t || "",
selected: t === tag.value,
})),
);
const posts = computed(() => {
if (tags.value.length > 0) {
return allPosts.value.filter((p) => {
return p.tags?.some((t) => {
return tags.value.includes(t);
});
});
if (tag.value) {
return allPosts.value?.filter((p) => p?.tags?.includes(tag.value));
}
return allPosts.value;
});
Expand All @@ -22,6 +29,15 @@ function getFormatedDate(dateString: string) {
return format(dateString, "yyyy年M月d日");
}
function onChangeTag(event: Event) {
const value = event.target.value;
router.push({
query: {
tag: value ? value : undefined,
},
});
}
useHead(() => ({
link: [
{
Expand All @@ -33,14 +49,12 @@ useHead(() => ({
</script>

<template>
<section v-if="tags.length > 0" class="flex gap-x-2 items-center px-6 sm:px-12 my-6">
<h1 class="font-bold">絞り込みタグ:</h1>
<ul class="flex gap-2">
<li v-for="(tag, i) in tags" :key="i">
<nuxt-link :to="`/?tags=${tag}`" class="text-sm block px-2 py-1 text-gray-700 bg-blue-100 hover:bg-blue-200">{{ tag }}</nuxt-link>
</li>
</ul>
</section>
<div class="flex gap-x-2 items-center px-6 sm:px-12 my-6">
<p class="font-bold">絞り込みタグ:</p>
<select @change="onChangeTag" class="p-2 bg-gray-100 border border-gray-400 dark:text-gray-900">
<option v-for="(option, i) in tagOptions" :key="i" :value="option.value" :selected="option.selected">{{ option.label }}</option>
</select>
</div>
<section class="px-6 sm:px-12 my-12" v-for="(post, i) in posts" :key="i">
<h1 class="text-2xl">
<nuxt-link class="link underline hover:no-underline" :to="`/posts${post.path}`">
Expand All @@ -51,7 +65,7 @@ useHead(() => ({
<time class="text-sm" :datetime="post.date">{{ getFormatedDate(post.date) }}</time>
<ul v-if="post.tags" v-for="(tag, i) in post.tags" :key="i" class="flex gap-4 items-center ml-4">
<li>
<nuxt-link :to="`/?tags=${tag}`" class="text-xs block px-2 py-1 text-gray-700 bg-blue-100 hover:bg-blue-200">{{ tag }}</nuxt-link>
<nuxt-link :to="`/?tag=${tag}`" class="text-xs block px-2 py-1 text-gray-700 bg-blue-100 hover:bg-blue-200">{{ tag }}</nuxt-link>
</li>
</ul>
</div>
Expand Down
2 changes: 1 addition & 1 deletion pages/posts/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ onMounted(() => {
<time :datetime="date" class="text-sm text-gray-600 dark:text-gray-200">{{ formatedDate }}</time>
<ul v-if="tags" v-for="(tag, i) in tags" :key="i" class="flex gap-4 items-center ml-4">
<li>
<nuxt-link :to="`/?tags=${tag}`" class="text-xs block px-2 py-1 text-gray-700 bg-blue-100 hover:bg-blue-200">{{ tag }}</nuxt-link>
<nuxt-link :to="`/?tag=${tag}`" class="text-xs block px-2 py-1 text-gray-700 bg-blue-100 hover:bg-blue-200">{{ tag }}</nuxt-link>
</li>
</ul>
</div>
Expand Down
20 changes: 20 additions & 0 deletions server/api/tags/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { readFileSync, readdirSync } from "node:fs";
import parseMD from "parse-md";

export default defineEventHandler(async () => {
const posts = readdirSync("./posts").reverse();
const result = new Set();

for (const post of posts) {
const file = readFileSync(`./posts/${post}`);
const { metadata } = parseMD(file.toString()) as { metadata: Metadata };
const tags = metadata.tags;

if (tags) {
for (const tag of tags) {
result.add(tag);
}
}
}
return [...result];
});

0 comments on commit a7c2c3e

Please sign in to comment.