Skip to content

Commit e7382c4

Browse files
KianNHkodster28
andauthored
[Docs Site] Create videos pages (#23842)
* [Docs Site] Create videos pages * support videos in ResourcesBySelector & add /videos/ * fix videos url * remove example video --------- Co-authored-by: kodster28 <[email protected]>
1 parent 379e731 commit e7382c4

File tree

6 files changed

+120
-80
lines changed

6 files changed

+120
-80
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: 33 additions & 19 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,21 +80,30 @@ export default function ResourcesBySelector({
7580
</div>
7681
)}
7782

78-
<div className="grid grid-cols-2 gap-4">
79-
{visibleResources.map((page) => (
80-
<a
81-
key={page.id}
82-
href={`/${page.id}/`}
83-
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"
84-
>
85-
<p className="decoration-accent underline decoration-2 underline-offset-4">
86-
{page.data.title}
87-
</p>
88-
<span className="line-clamp-3" title={page.data.description}>
89-
{page.data.description}
90-
</span>
91-
</a>
92-
))}
83+
<div
84+
className={`grid ${columns === 2 ? "grid-cols-2" : "grid-cols-3"} gap-4`}
85+
>
86+
{visibleResources.map((page) => {
87+
const href =
88+
page.collection === "stream"
89+
? `/videos/${page.data.url}/`
90+
: `/${page.id}/`;
91+
92+
return (
93+
<a
94+
key={page.id}
95+
href={href}
96+
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"
97+
>
98+
<p className="decoration-accent underline decoration-2 underline-offset-4">
99+
{page.data.title}
100+
</p>
101+
<span className="line-clamp-3" title={page.data.description}>
102+
{page.data.description}
103+
</span>
104+
</a>
105+
);
106+
})}
93107
</div>
94108
</div>
95109
);

src/content/stream/example-video/index.yaml

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/content/stream/example-video/transcript.vtt

Lines changed: 0 additions & 40 deletions
This file was deleted.

src/pages/videos/[...slug].astro

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
import type { GetStaticPaths } from "astro";
3+
import { getCollection } from "astro:content";
4+
import StarlightPage, {
5+
type StarlightPageProps,
6+
} from "@astrojs/starlight/components/StarlightPage.astro";
7+
8+
import { Stream, Width } from "~/components";
9+
10+
export const getStaticPaths = (async () => {
11+
const entries = await getCollection("stream");
12+
13+
return entries.map(({ data }) => {
14+
return {
15+
params: {
16+
slug: data.url,
17+
},
18+
props: {
19+
entry: data,
20+
},
21+
};
22+
});
23+
}) satisfies GetStaticPaths;
24+
25+
const { entry } = Astro.props;
26+
27+
const props = {
28+
frontmatter: {
29+
title: entry.title,
30+
description: entry.description,
31+
template: "splash",
32+
noindex: true,
33+
},
34+
hideBreadcrumbs: true,
35+
} as StarlightPageProps;
36+
---
37+
38+
<StarlightPage {...props}>
39+
<Width size="large" center={true}>
40+
<Stream id={entry.id} title={entry.title} chapters={entry.chapters} />
41+
</Width>
42+
</StarlightPage>

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)