Add tags filter

main
adb-sh 5 months ago
parent 359b5dc907
commit 500e6c69db

@ -1,5 +1,6 @@
import { createSignal, For, Show } from "solid-js"; import { createSignal, For, createMemo } from "solid-js";
import { cache, createAsync, A, type RouteDefinition } from "@solidjs/router"; import { cache, createAsync, A, type RouteDefinition } from "@solidjs/router";
import { classList } from "solid-js/web";
const getNewsList = cache(async () => { const getNewsList = cache(async () => {
"use server"; "use server";
@ -24,19 +25,51 @@ export const route = {
export default () => { export default () => {
const newsList = createAsync(() => getNewsList()); const newsList = createAsync(() => getNewsList());
const tags = createAsync(() => getNewsTags()); const tagsData = createAsync(() => getNewsTags());
const [tags, setTags] = createSignal(
Object.fromEntries(
tagsData()?.map((tag: string) => [tag, { active: false }]) ?? []
)
);
const tagsActive = createMemo(() =>
Object.entries(tags())
.filter(([, { active }]) => active)
.map(([tag]) => tag)
);
return ( return (
<main class="container mx-auto p-4"> <main class="container mx-auto p-4">
<h1 class="mb-12 mt-40">News</h1> <h1 class="mb-12 mt-40">News</h1>
<div class="flex flex-wrap gap-2"> <div class="flex flex-wrap gap-2">
<For each={tags()}> <For each={Object.entries(tags())}>
{(tag) => ( {([tag, { active }]) => (
<button class="btn btn-sm">{tag}</button> <button
class="btn btn-sm"
classList={{ "btn-primary": active }}
onClick={() =>
setTags({
...tags(),
[tag]: { active: !active },
})
}
>
{tag}
</button>
)} )}
</For> </For>
</div> </div>
<For each={newsList()}> <For
each={
tagsActive()?.length
? newsList()?.filter((news) =>
Object.entries(tags())
.filter(([, state]) => state.active)
.some(([tag]) => news.keywords.includes(tag))
)
: newsList()
}
>
{(post) => ( {(post) => (
<A href={`/news/${post.slug}`}> <A href={`/news/${post.slug}`}>
<figure class="card md:card-side bg-base-100 shadow-xl mt-4"> <figure class="card md:card-side bg-base-100 shadow-xl mt-4">
@ -49,6 +82,11 @@ export default () => {
<h2 class="card-title">{post.title}</h2> <h2 class="card-title">{post.title}</h2>
<p>{post.published}</p> <p>{post.published}</p>
<p>{post.description}</p> <p>{post.description}</p>
<div class="flex gap-2">
<For each={post.keywords}>
{(tag) => <div class="badge badge-secondary">{tag}</div>}
</For>
</div>
</div> </div>
</figure> </figure>
</A> </A>

Loading…
Cancel
Save