Skip to content

Commit 6783d07

Browse files
Community Resources Pages (#517)
* community resource page * fix some things
1 parent c2c8b7b commit 6783d07

File tree

4 files changed

+187
-0
lines changed

4 files changed

+187
-0
lines changed

src/components/DocsLayout.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,14 @@ const useMenuConfig = ({
7474
label: 'Contributors',
7575
to: '/$libraryId/$version/docs/contributors',
7676
},
77+
...(config.sections.find((d) => d.label === 'Community Resources')
78+
? [
79+
{
80+
label: 'Community Resources',
81+
to: '/$libraryId/$version/docs/community-resources',
82+
},
83+
]
84+
: []),
7785
{
7886
label: (
7987
<div className="flex items-center gap-2">

src/routeTree.gen.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import { Route as LibrariesConfigVersionIndexRouteImport } from './routes/_libra
5555
import { Route as LibraryIdVersionDocsIndexRouteImport } from './routes/$libraryId/$version.docs.index'
5656
import { Route as LibraryIdVersionDocsChar123Char125DotmdRouteImport } from './routes/$libraryId/$version.docs.{$}[.]md'
5757
import { Route as LibraryIdVersionDocsContributorsRouteImport } from './routes/$libraryId/$version.docs.contributors'
58+
import { Route as LibraryIdVersionDocsCommunityResourcesDotmdRouteImport } from './routes/$libraryId/$version.docs.community-resources[.]md'
5859
import { Route as LibraryIdVersionDocsSplatRouteImport } from './routes/$libraryId/$version.docs.$'
5960
import { Route as LibraryIdVersionDocsFrameworkIndexRouteImport } from './routes/$libraryId/$version.docs.framework.index'
6061
import { Route as LibraryIdVersionDocsFrameworkFrameworkIndexRouteImport } from './routes/$libraryId/$version.docs.framework.$framework.index'
@@ -305,6 +306,12 @@ const LibraryIdVersionDocsContributorsRoute =
305306
path: '/contributors',
306307
getParentRoute: () => LibraryIdVersionDocsRoute,
307308
} as any)
309+
const LibraryIdVersionDocsCommunityResourcesDotmdRoute =
310+
LibraryIdVersionDocsCommunityResourcesDotmdRouteImport.update({
311+
id: '/community-resources.md',
312+
path: '/community-resources.md',
313+
getParentRoute: () => LibraryIdVersionDocsRoute,
314+
} as any)
308315
const LibraryIdVersionDocsSplatRoute =
309316
LibraryIdVersionDocsSplatRouteImport.update({
310317
id: '/$',
@@ -374,6 +381,7 @@ export interface FileRoutesByFullPath {
374381
'/blog/': typeof LibrariesBlogIndexRoute
375382
'/stats/npm': typeof StatsNpmIndexRoute
376383
'/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute
384+
'/$libraryId/$version/docs/community-resources.md': typeof LibraryIdVersionDocsCommunityResourcesDotmdRoute
377385
'/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute
378386
'/$libraryId/$version/docs/{$}.md': typeof LibraryIdVersionDocsChar123Char125DotmdRoute
379387
'/$libraryId/$version/docs/': typeof LibraryIdVersionDocsIndexRoute
@@ -423,6 +431,7 @@ export interface FileRoutesByTo {
423431
'/blog': typeof LibrariesBlogIndexRoute
424432
'/stats/npm': typeof StatsNpmIndexRoute
425433
'/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute
434+
'/$libraryId/$version/docs/community-resources.md': typeof LibraryIdVersionDocsCommunityResourcesDotmdRoute
426435
'/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute
427436
'/$libraryId/$version/docs/{$}.md': typeof LibraryIdVersionDocsChar123Char125DotmdRoute
428437
'/$libraryId/$version/docs': typeof LibraryIdVersionDocsIndexRoute
@@ -478,6 +487,7 @@ export interface FileRoutesById {
478487
'/_libraries/blog/': typeof LibrariesBlogIndexRoute
479488
'/stats/npm/': typeof StatsNpmIndexRoute
480489
'/$libraryId/$version/docs/$': typeof LibraryIdVersionDocsSplatRoute
490+
'/$libraryId/$version/docs/community-resources.md': typeof LibraryIdVersionDocsCommunityResourcesDotmdRoute
481491
'/$libraryId/$version/docs/contributors': typeof LibraryIdVersionDocsContributorsRoute
482492
'/$libraryId/$version/docs/{$}.md': typeof LibraryIdVersionDocsChar123Char125DotmdRoute
483493
'/$libraryId/$version/docs/': typeof LibraryIdVersionDocsIndexRoute
@@ -533,6 +543,7 @@ export interface FileRouteTypes {
533543
| '/blog/'
534544
| '/stats/npm'
535545
| '/$libraryId/$version/docs/$'
546+
| '/$libraryId/$version/docs/community-resources.md'
536547
| '/$libraryId/$version/docs/contributors'
537548
| '/$libraryId/$version/docs/{$}.md'
538549
| '/$libraryId/$version/docs/'
@@ -582,6 +593,7 @@ export interface FileRouteTypes {
582593
| '/blog'
583594
| '/stats/npm'
584595
| '/$libraryId/$version/docs/$'
596+
| '/$libraryId/$version/docs/community-resources.md'
585597
| '/$libraryId/$version/docs/contributors'
586598
| '/$libraryId/$version/docs/{$}.md'
587599
| '/$libraryId/$version/docs'
@@ -636,6 +648,7 @@ export interface FileRouteTypes {
636648
| '/_libraries/blog/'
637649
| '/stats/npm/'
638650
| '/$libraryId/$version/docs/$'
651+
| '/$libraryId/$version/docs/community-resources.md'
639652
| '/$libraryId/$version/docs/contributors'
640653
| '/$libraryId/$version/docs/{$}.md'
641654
| '/$libraryId/$version/docs/'
@@ -995,6 +1008,13 @@ declare module '@tanstack/react-router' {
9951008
preLoaderRoute: typeof LibraryIdVersionDocsContributorsRouteImport
9961009
parentRoute: typeof LibraryIdVersionDocsRoute
9971010
}
1011+
'/$libraryId/$version/docs/community-resources.md': {
1012+
id: '/$libraryId/$version/docs/community-resources.md'
1013+
path: '/community-resources.md'
1014+
fullPath: '/$libraryId/$version/docs/community-resources.md'
1015+
preLoaderRoute: typeof LibraryIdVersionDocsCommunityResourcesDotmdRouteImport
1016+
parentRoute: typeof LibraryIdVersionDocsRoute
1017+
}
9981018
'/$libraryId/$version/docs/$': {
9991019
id: '/$libraryId/$version/docs/$'
10001020
path: '/$'
@@ -1042,6 +1062,7 @@ declare module '@tanstack/react-router' {
10421062

10431063
interface LibraryIdVersionDocsRouteChildren {
10441064
LibraryIdVersionDocsSplatRoute: typeof LibraryIdVersionDocsSplatRoute
1065+
LibraryIdVersionDocsCommunityResourcesDotmdRoute: typeof LibraryIdVersionDocsCommunityResourcesDotmdRoute
10451066
LibraryIdVersionDocsContributorsRoute: typeof LibraryIdVersionDocsContributorsRoute
10461067
LibraryIdVersionDocsChar123Char125DotmdRoute: typeof LibraryIdVersionDocsChar123Char125DotmdRoute
10471068
LibraryIdVersionDocsIndexRoute: typeof LibraryIdVersionDocsIndexRoute
@@ -1054,6 +1075,8 @@ interface LibraryIdVersionDocsRouteChildren {
10541075

10551076
const LibraryIdVersionDocsRouteChildren: LibraryIdVersionDocsRouteChildren = {
10561077
LibraryIdVersionDocsSplatRoute: LibraryIdVersionDocsSplatRoute,
1078+
LibraryIdVersionDocsCommunityResourcesDotmdRoute:
1079+
LibraryIdVersionDocsCommunityResourcesDotmdRoute,
10571080
LibraryIdVersionDocsContributorsRoute: LibraryIdVersionDocsContributorsRoute,
10581081
LibraryIdVersionDocsChar123Char125DotmdRoute:
10591082
LibraryIdVersionDocsChar123Char125DotmdRoute,
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { createFileRoute } from '@tanstack/react-router'
2+
import { twMerge } from 'tailwind-merge'
3+
import { DocContainer } from '~/components/DocContainer'
4+
import { DocTitle } from '~/components/DocTitle'
5+
import { findLibrary, getBranch, getLibrary } from '~/libraries'
6+
import { seo } from '~/utils/seo'
7+
import { loadDocs } from '~/utils/docs'
8+
9+
export const Route = createFileRoute(
10+
'/$libraryId/$version/docs/community-resources.md'
11+
)({
12+
staleTime: 1000 * 60 * 5,
13+
loader: async (ctx) => {
14+
const { libraryId, version } = ctx.params
15+
const library = findLibrary(libraryId)
16+
17+
if (!library) return { doc: null as null | any }
18+
19+
const root = library.docsRoot || 'docs'
20+
21+
try {
22+
const doc = await loadDocs({
23+
repo: library.repo,
24+
branch: getBranch(library, version),
25+
docsPath: `${root}/community-resources`,
26+
currentPath: ctx.location.pathname,
27+
redirectPath: `/${library.id}/${version}/docs/overview`,
28+
})
29+
30+
return { doc }
31+
} catch {
32+
return { doc: null as null | any }
33+
}
34+
},
35+
head: ({ params, loaderData }) => {
36+
const library = getLibrary(params.libraryId)
37+
const doc = (loaderData as any)?.doc
38+
return {
39+
meta: seo({
40+
title: `${library.name} Community Resources`,
41+
description: `A collection of community resources for ${library.name}.`,
42+
}),
43+
}
44+
},
45+
component: RouteComponent,
46+
})
47+
48+
type ResourceType = 'article' | 'media' | 'utility' | 'other'
49+
50+
type Resource = {
51+
title: string
52+
description: string
53+
url: string
54+
}
55+
56+
function RouteComponent() {
57+
const { libraryId } = Route.useParams()
58+
const library = getLibrary(libraryId)
59+
const data = Route.useLoaderData().doc?.frontmatter
60+
61+
return (
62+
<DocContainer>
63+
<div
64+
className={twMerge(
65+
'w-full flex flex-col bg-white/70 dark:bg-black/40 mx-auto rounded-xl max-w-[1200px]'
66+
)}
67+
>
68+
<div className="p-4 lg:p-6 flex flex-col space-y-4 w-full">
69+
<div className={twMerge('flex overflow-auto flex-col w-full')}>
70+
<DocTitle>
71+
{(data?.title as string | undefined) ||
72+
`${library.name} Community Resources`}
73+
</DocTitle>
74+
<div className="h-4" />
75+
<div className="h-px bg-gray-500 opacity-20" />
76+
</div>
77+
<span>
78+
{(data?.frontmatter?.description as string | undefined) || (
79+
<>
80+
Discover resources created by the{' '}
81+
<strong>{library.name}</strong> community. Have something to
82+
share?{' '}
83+
<a
84+
href={`https://github.com/${libraryId}/edit/main/docs/community-resources.md`}
85+
target="_blank"
86+
rel="noopener noreferrer"
87+
className="underline"
88+
>
89+
Submit a PR on GitHub
90+
</a>{' '}
91+
to contribute to this list.
92+
</>
93+
)}
94+
</span>
95+
{data?.frontmatter?.articles > 1 && (
96+
<CommunitySection
97+
type="article"
98+
resources={data.frontmatter.articles as Resource[]}
99+
/>
100+
)}
101+
{data?.frontmatter?.media > 1 && (
102+
<CommunitySection
103+
type="media"
104+
resources={data.frontmatter.media as Resource[]}
105+
/>
106+
)}
107+
{data?.frontmatter?.utilities > 1 && (
108+
<CommunitySection
109+
type="utility"
110+
resources={data.frontmatter.utilities as Resource[]}
111+
/>
112+
)}
113+
{data?.frontmatter?.others > 1 && (
114+
<CommunitySection
115+
type="other"
116+
resources={data.frontmatter.others as Resource[]}
117+
/>
118+
)}
119+
</div>
120+
</div>
121+
</DocContainer>
122+
)
123+
}
124+
125+
function CommunitySection({
126+
resources,
127+
type,
128+
}: {
129+
resources: Resource[]
130+
type: ResourceType
131+
}) {
132+
return (
133+
<section>
134+
<h2 className="text-[1.5rem] font-semibold pb-4 capitalize">{type}</h2>
135+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 ">
136+
{resources.map((res) => (
137+
<a
138+
key={res.url}
139+
href={res.url}
140+
className="flex flex-wrap items-center space-y-2 dark:text-gray-500 p-3 cursor-pointer bg-white dark:bg-white/5 rounded-lg overflow-hidden shadow-lg hover:bg-gray-100 dark:hover:bg-white/10 transition-colors border border-1 border-gray-200 dark:border-gray-700"
141+
>
142+
<span className="text-base font-bold text-gray-800 dark:text-white truncate">
143+
{res.title}
144+
</span>
145+
<div className="h-2" />
146+
<div className="h-px bg-gray-500 opacity-20 w-full" />
147+
<p className="text-sm dark:text-gray-400 text-gray-50 line-clamp-3 w-full h-14">
148+
{res.description}
149+
</p>
150+
</a>
151+
))}
152+
</div>
153+
</section>
154+
)
155+
}

src/utils/docs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ export const fetchDocs = createServerFn({ method: 'GET' })
8585
description,
8686
filePath,
8787
content: frontMatter.content,
88+
frontmatter: frontMatter.data,
8889
}
8990
})
9091

0 commit comments

Comments
 (0)