Skip to content

Commit 712922a

Browse files
committed
feat: contributors pages for repos
1 parent b2b4dd8 commit 712922a

8 files changed

Lines changed: 487 additions & 2 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { type Library } from '~/libraries'
2+
3+
export function ContributorsWall({ library }: { library: Library }) {
4+
return (
5+
<div className="flex flex-col items-center my-4">
6+
<a
7+
href={`https://github.com/tanstack/${library.id}/graphs/contributors`}
8+
target="_blank"
9+
rel="noopener noreferrer"
10+
>
11+
<img
12+
alt="GitHub Contributors"
13+
src={`https://contrib.rocks/image?repo=tanstack/${library.id}`}
14+
loading="lazy"
15+
/>
16+
</a>
17+
</div>
18+
)
19+
}

src/components/DocsLayout.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ const useMenuConfig = ({
197197
},
198198
]
199199
: []),
200+
{
201+
label: 'Contributors',
202+
to: '/$libraryId/$version/docs/contributors',
203+
},
200204
{
201205
label: (
202206
<div className="flex items-center gap-2">

src/components/MaintainerCard.tsx

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { Library } from '~/libraries'
2+
import { getRoleInLibrary, Maintainer } from '~/libraries/maintainers'
3+
4+
function RoleBadge({ role, libraryId }: { role: string; libraryId: string }) {
5+
const isCreator = role.toLowerCase().includes('creator')
6+
const isMaintainer = role.toLowerCase().includes('maintainer')
7+
8+
if (isCreator) {
9+
return (
10+
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gradient-to-r from-purple-500 to-pink-500 text-white shadow-lg">
11+
{role}
12+
</span>
13+
)
14+
}
15+
16+
if (isMaintainer) {
17+
return (
18+
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-500 text-white">
19+
{role}
20+
</span>
21+
)
22+
}
23+
24+
return <span className="text-gray-500 dark:text-gray-400">{role}</span>
25+
}
26+
27+
interface MaintainerCardProps {
28+
maintainer: Maintainer
29+
libraryId: Library['id']
30+
}
31+
32+
export function MaintainerCard({ maintainer, libraryId }: MaintainerCardProps) {
33+
return (
34+
<a
35+
href={`https://github.com/${maintainer.github}`}
36+
className="group bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-lg"
37+
target="_blank"
38+
rel="noopener noreferrer"
39+
>
40+
<div className="relative h-64 overflow-hidden">
41+
<img
42+
alt={`${maintainer.name}'s avatar`}
43+
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
44+
src={maintainer.avatar}
45+
style={{
46+
aspectRatio: '1/1',
47+
objectFit: 'cover',
48+
}}
49+
/>
50+
<div className="absolute inset-0 bg-gradient-to-t from-black/10 to-transparent" />
51+
</div>
52+
<div className="p-4 space-y-2">
53+
<div>
54+
<h3 className="text-lg font-bold">{maintainer.name}</h3>
55+
<p className="mt-1">
56+
<RoleBadge
57+
role={getRoleInLibrary(maintainer, libraryId)}
58+
libraryId={libraryId}
59+
/>
60+
</p>
61+
<p className="text-gray-500 dark:text-gray-400 mt-2">
62+
<span className="inline-block w-5 text-center">
63+
<svg
64+
viewBox="0 0 16 16"
65+
className="w-4 h-4 inline-block"
66+
fill="currentColor"
67+
>
68+
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path>
69+
</svg>
70+
</span>
71+
@{maintainer.github}
72+
</p>
73+
</div>
74+
<ul className="flex flex-wrap">
75+
{maintainer.specialties?.map((specialty: string) => (
76+
<li
77+
className="bg-gray-500/10 text-xs text-gray-500 dark:text-white rounded-full px-2 py-1 mr-2 mb-2"
78+
key={specialty}
79+
>
80+
{specialty}
81+
</li>
82+
))}
83+
</ul>
84+
</div>
85+
</a>
86+
)
87+
}

src/libraries/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export type Library = {
5757
| 'db'
5858
| 'config'
5959
| 'react-charts'
60+
| 'create-ts-router-app'
6061
name: string
6162
cardStyles: string
6263
to: string
@@ -125,7 +126,6 @@ export const librariesByGroup = {
125126
}
126127

127128
export const librariesGroupNamesMap = {
128-
app: 'Application Building',
129129
state: 'Data and State Management',
130130
headlessUI: 'Headless UI',
131131
other: 'Other',
@@ -165,3 +165,4 @@ export function getBranch(library: Library, argVersion?: string) {
165165

166166
return resolvedVersion
167167
}
168+

0 commit comments

Comments
 (0)