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 { 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…
Reference in New Issue
Block a user