Add tags filter
This commit is contained in:
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 { classList } from "solid-js/web";
|
||||
|
||||
const getNewsList = cache(async () => {
|
||||
"use server";
|
||||
@ -24,19 +25,51 @@ export const route = {
|
||||
|
||||
export default () => {
|
||||
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 (
|
||||
<main class="container mx-auto p-4">
|
||||
<h1 class="mb-12 mt-40">News</h1>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<For each={tags()}>
|
||||
{(tag) => (
|
||||
<button class="btn btn-sm">{tag}</button>
|
||||
<For each={Object.entries(tags())}>
|
||||
{([tag, { active }]) => (
|
||||
<button
|
||||
class="btn btn-sm"
|
||||
classList={{ "btn-primary": active }}
|
||||
onClick={() =>
|
||||
setTags({
|
||||
...tags(),
|
||||
[tag]: { active: !active },
|
||||
})
|
||||
}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
</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) => (
|
||||
<A href={`/news/${post.slug}`}>
|
||||
<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>
|
||||
<p>{post.published}</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>
|
||||
</figure>
|
||||
</A>
|
||||
|
Loading…
Reference in New Issue
Block a user