Skip to content

Commit 071e616

Browse files
committed
move to React component
1 parent f9835ac commit 071e616

File tree

2 files changed

+88
-38
lines changed

2 files changed

+88
-38
lines changed
Lines changed: 7 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
import { z } from "astro:schema";
33
import { getCollection, type CollectionEntry } from "astro:content";
4-
import ReactSelect from "./ReactSelect";
4+
import ResourcesBySelectorReact from "./ResourcesBySelector";
55
66
type Props = z.infer<typeof props>;
77
type Frontmatter = keyof CollectionEntry<"docs">["data"];
@@ -46,40 +46,9 @@ const facets = resources.reduce(
4646
);
4747
---
4848

49-
{
50-
filters && (
51-
<div class="not-content">
52-
<ReactSelect
53-
id="resources-filters"
54-
className="mt-2"
55-
options={Object.entries(facets).map(([key, values]) => ({
56-
label: key,
57-
options: values.map((v) => ({
58-
value: v,
59-
label: v,
60-
})),
61-
}))}
62-
onChange={(opt) => console.log(opt)}
63-
client:idle
64-
/>
65-
</div>
66-
)
67-
}
68-
69-
<div class="grid grid-cols-2 gap-4">
70-
{
71-
resources.map((page) => (
72-
<a
73-
href={`/${page.id}/`}
74-
class="flex flex-col gap-2 rounded-sm border border-solid border-gray-200 p-6 text-black no-underline hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-800"
75-
>
76-
<p class="decoration-accent underline decoration-2 underline-offset-4">
77-
{page.data.title}
78-
</p>
79-
<span class="line-clamp-3" title={page.data.description}>
80-
{page.data.description}
81-
</span>
82-
</a>
83-
))
84-
}
85-
</div>
49+
<ResourcesBySelectorReact
50+
resources={resources}
51+
facets={facets}
52+
filters={filters}
53+
client:load
54+
/>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { useState } from "react";
2+
import ReactSelect from "./ReactSelect";
3+
import type { CollectionEntry } from "astro:content";
4+
5+
type Frontmatter = keyof CollectionEntry<"docs">["data"];
6+
7+
interface Props {
8+
resources: CollectionEntry<"docs">[];
9+
facets: Record<string, string[]>;
10+
filters?: Frontmatter[];
11+
}
12+
13+
export default function ResourcesBySelector({
14+
resources,
15+
facets,
16+
filters,
17+
}: Props) {
18+
const [selectedFilter, setSelectedFilter] = useState<string | null>(null);
19+
20+
const handleFilterChange = (option: any) => {
21+
setSelectedFilter(option?.value || null);
22+
};
23+
24+
const visibleResources = resources.filter((resource) => {
25+
if (!selectedFilter || !filters) return true;
26+
27+
const filterableValues: string[] = [];
28+
for (const filter of filters) {
29+
const val = resource.data[filter];
30+
if (val) {
31+
if (Array.isArray(val) && val.every((v) => typeof v === "string")) {
32+
filterableValues.push(...val);
33+
} else if (typeof val === "string") {
34+
filterableValues.push(val);
35+
}
36+
}
37+
}
38+
39+
return filterableValues.includes(selectedFilter);
40+
});
41+
42+
return (
43+
<div>
44+
{filters && (
45+
<div className="not-content">
46+
<ReactSelect
47+
id="resources-filters"
48+
className="mt-2"
49+
options={Object.entries(facets).map(([key, values]) => ({
50+
label: key,
51+
options: values.map((v) => ({
52+
value: v,
53+
label: v,
54+
})),
55+
}))}
56+
onChange={handleFilterChange}
57+
isClearable
58+
placeholder="Filter resources..."
59+
/>
60+
</div>
61+
)}
62+
63+
<div className="grid grid-cols-2 gap-4">
64+
{visibleResources.map((page) => (
65+
<a
66+
key={page.id}
67+
href={`/${page.id}/`}
68+
className="flex flex-col gap-2 rounded-sm border border-solid border-gray-200 p-6 text-black no-underline hover:bg-gray-50 dark:border-gray-700 dark:hover:bg-gray-800"
69+
>
70+
<p className="decoration-accent underline decoration-2 underline-offset-4">
71+
{page.data.title}
72+
</p>
73+
<span className="line-clamp-3" title={page.data.description}>
74+
{page.data.description}
75+
</span>
76+
</a>
77+
))}
78+
</div>
79+
</div>
80+
);
81+
}

0 commit comments

Comments
 (0)