Skip to content

Commit 7e3cd84

Browse files
committed
support videos in ResourcesBySelector & add /videos/
1 parent a703129 commit 7e3cd84

File tree

3 files changed

+57
-13
lines changed

3 files changed

+57
-13
lines changed

src/components/ResourcesBySelector.astro

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,43 @@ import { z } from "astro:schema";
33
import { getCollection, type CollectionEntry } from "astro:content";
44
import ResourcesBySelectorReact from "./ResourcesBySelector";
55
6-
type Props = z.infer<typeof props>;
7-
type Frontmatter = keyof CollectionEntry<"docs">["data"];
6+
type Props = z.input<typeof props>;
7+
8+
type DocsData = keyof CollectionEntry<"docs">["data"];
9+
type VideosData = keyof CollectionEntry<"stream">["data"];
10+
11+
type ResourcesData = DocsData | VideosData;
812
913
const props = z.object({
1014
tags: z.string().array().optional(),
1115
types: z.string().array(),
1216
products: z.string().array().optional(),
1317
directory: z.string().optional(),
14-
filterables: z.custom<Frontmatter>().array().optional(),
18+
filterables: z.custom<ResourcesData>().array().optional(),
19+
columns: z.union([z.literal(2), z.literal(3)]).default(2),
1520
});
1621
17-
const { tags, types, products, directory, filterables } = props.parse(
22+
const { tags, types, products, directory, filterables, columns } = props.parse(
1823
Astro.props,
1924
);
2025
21-
const resources = await getCollection("docs", ({ id, data }) => {
26+
const docs = await getCollection("docs");
27+
const videos = await getCollection("stream");
28+
29+
const resources: Array<CollectionEntry<"docs"> | CollectionEntry<"stream">> = [
30+
...docs,
31+
...videos,
32+
].filter(({ id, collection, data }) => {
33+
const type = "pcx_content_type" in data ? data.pcx_content_type : collection;
2234
return (
23-
types.includes(data.pcx_content_type ?? "") &&
35+
types.includes(type ?? "") &&
2436
(directory ? id.startsWith(directory) : true) &&
2537
(tags ? data.tags?.some((v: string) => tags.includes(v)) : true) &&
26-
(products ? data.products?.some((v: string) => products.includes(v)) : true)
38+
(products
39+
? data.products?.some((v) =>
40+
products.includes(typeof v === "object" ? v.id : v),
41+
)
42+
: true)
2743
);
2844
});
2945
@@ -32,7 +48,7 @@ const facets = resources.reduce(
3248
if (!filterables) return acc;
3349
3450
for (const filter of filterables) {
35-
const val = page.data[filter];
51+
const val = page.data[filter as keyof typeof page.data];
3652
if (val) {
3753
if (Array.isArray(val) && val.every((v) => typeof v === "string")) {
3854
acc[filter] = [...new Set([...(acc[filter] || []), ...val])];
@@ -53,6 +69,7 @@ const facets = resources.reduce(
5369
resources={resources}
5470
facets={facets}
5571
filters={filterables}
72+
columns={columns}
5673
client:load
5774
/>
5875
</div>

src/components/ResourcesBySelector.tsx

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@ import { useEffect, useState } from "react";
22
import ReactSelect from "./ReactSelect";
33
import type { CollectionEntry } from "astro:content";
44

5-
type Frontmatter = keyof CollectionEntry<"docs">["data"];
5+
type DocsData = keyof CollectionEntry<"docs">["data"];
6+
type VideosData = keyof CollectionEntry<"stream">["data"];
7+
8+
type ResourcesData = DocsData | VideosData;
69

710
interface Props {
8-
resources: CollectionEntry<"docs">[];
11+
resources: Array<CollectionEntry<"docs"> | CollectionEntry<"stream">>;
912
facets: Record<string, string[]>;
10-
filters?: Frontmatter[];
13+
filters?: ResourcesData[];
14+
columns: number;
1115
}
1216

1317
export default function ResourcesBySelector({
1418
resources,
1519
facets,
1620
filters,
21+
columns,
1722
}: Props) {
1823
const [selectedFilter, setSelectedFilter] = useState<string | null>(null);
1924

@@ -34,7 +39,7 @@ export default function ResourcesBySelector({
3439

3540
const filterableValues: string[] = [];
3641
for (const filter of filters) {
37-
const val = resource.data[filter];
42+
const val = resource.data[filter as keyof typeof resource.data];
3843
if (val) {
3944
if (Array.isArray(val) && val.every((v) => typeof v === "string")) {
4045
filterableValues.push(...val);
@@ -75,7 +80,9 @@ export default function ResourcesBySelector({
7580
</div>
7681
)}
7782

78-
<div className="grid grid-cols-2 gap-4">
83+
<div
84+
className={`grid ${columns === 2 ? "grid-cols-2" : "grid-cols-3"} gap-4`}
85+
>
7986
{visibleResources.map((page) => (
8087
<a
8188
key={page.id}

src/pages/videos/index.astro

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
import StarlightPage, {
3+
type StarlightPageProps,
4+
} from "@astrojs/starlight/components/StarlightPage.astro";
5+
6+
import { ResourcesBySelector } from "~/components";
7+
8+
const props = {
9+
frontmatter: {
10+
title: "Videos",
11+
template: "splash",
12+
noindex: true,
13+
},
14+
hideBreadcrumbs: true,
15+
} as StarlightPageProps;
16+
---
17+
18+
<StarlightPage {...props}>
19+
<ResourcesBySelector types={["stream"]} columns={3} />
20+
</StarlightPage>

0 commit comments

Comments
 (0)