diff --git a/src/data/contributors-manual.json b/src/data/contributors-manual.json index ff4c6b8..7cd5f62 100644 --- a/src/data/contributors-manual.json +++ b/src/data/contributors-manual.json @@ -1,18 +1,18 @@ { "generated_at": "2025-09-03T13:46:04.752Z", - "total_contributors": 1, + "total_contributors": 3, "total_contributions": 24, "total_impact_score": 24, "total_recent_activity": 24, "scoring_method": "manual_entry", "contributors": [ { - "id": 999999999, + "id": 999999999, "login": "Robobc", "name": "Roberto Catalano", "avatar_url": "https://avatars.githubusercontent.com/u/999999999?v=4", "html_url": "https://github.com/Robobc", - "bio": "Solutions Architect at AWS in Zurich", + "bio": "Created some great example repositories and helped with the documentation.", "company": "Amazon Web Services", "location": "Zürich", "blog": null, @@ -33,6 +33,62 @@ "total_reviews": 0, "last_activity": "2025-09-03T13:46:04Z", "pr_success_rate": 0 + }, + { + "id": 0, + "login": "gwoodwa1", + "name": "Gary Woodward", + "avatar_url": "https://github.com/gwoodwa1.png", + "html_url": "https://github.com/gwoodwa1", + "bio": "Supported Go-port by giving gnmi support over grpc transport", + "company": null, + "location": null, + "blog": null, + "hireable": null, + "public_repos": 0, + "followers": 0, + "following": 0, + "created_at": null, + "contributions": 0, + "repositories": [ + "utcp-go" + ], + "repo_count": 1, + "impact_score": 0, + "total_prs": 0, + "total_merged_prs": 0, + "total_recent_commits": 0, + "total_reviews": 0, + "last_activity": null, + "pr_success_rate": 0 + }, + { + "id": 0, + "login": "armanzeroeight", + "name": "Arman Nourifar", + "avatar_url": "https://github.com/armanzeroeight.png", + "html_url": "https://github.com/armanzeroeight", + "bio": "For social media content and his excellent gifs", + "company": null, + "location": "Oslo, Norway", + "blog": "https://medium.com/@arman08", + "hireable": null, + "public_repos": 0, + "followers": 0, + "following": 0, + "created_at": null, + "contributions": 0, + "repositories": [ + "community" + ], + "repo_count": 1, + "impact_score": 0, + "total_prs": 0, + "total_merged_prs": 0, + "total_recent_commits": 0, + "total_reviews": 0, + "last_activity": null, + "pr_success_rate": 0 } ] } diff --git a/src/pages/hall-of-fame.module.css b/src/pages/hall-of-fame.module.css index f2e79a2..c0ef90b 100644 --- a/src/pages/hall-of-fame.module.css +++ b/src/pages/hall-of-fame.module.css @@ -843,4 +843,88 @@ .linesChangedLabel { font-size: 0.4rem; } +} + +/* Other Contributors (non-coder) section */ +.otherContributorsSection { + padding: 3rem 1rem 0; + max-width: 1200px; + margin: 0 auto; +} + +.otherContributorsHeader { + text-align: center; + margin-bottom: 1.5rem; +} + +.otherContributorsTitle { + font-size: 2rem; + font-weight: 700; + margin: 0 0 0.5rem 0; + background: linear-gradient(135deg, #ffffff 0%, #8b5cf6 100%); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; +} + +.otherContributorsSubtitle { + font-size: 1rem; + color: #888888; + margin: 0; +} + +.otherContributorsGrid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 1rem; +} + +.otherContributorCard { + background: linear-gradient(145deg, #111111 0%, #0a0a0a 100%); + border: 1px solid #222222; + border-radius: 12px; + padding: 1rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.otherContributorIcon { + width: 72px; + height: 72px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 2rem; + background: linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 100%); + border: 1px solid #333333; +} + +.otherContributorImage { + width: 100%; + height: 100%; + border-radius: 50%; + object-fit: cover; +} + +.otherContributorRole { + font-size: 1.05rem; + font-weight: 600; + margin: 0.25rem 0 0; + color: #ffffff; +} + +.otherContributorThanks { + font-size: 0.9rem; + color: #cccccc; + margin: 0; + text-align: center; +} + +@media (max-width: 768px) { + .otherContributorsSection { + padding-top: 2rem; + } } \ No newline at end of file diff --git a/src/pages/hall-of-fame.tsx b/src/pages/hall-of-fame.tsx index df7da66..14d6fd3 100644 --- a/src/pages/hall-of-fame.tsx +++ b/src/pages/hall-of-fame.tsx @@ -472,6 +472,60 @@ const ContributorRow = ({ contributor, rank }: { contributor: DisplayContributor export default function Contributors(): React.ReactNode { const contributors = useContributors(); + const [otherContributors, setOtherContributors] = useState>([]); + + useEffect(() => { + const loadOtherContributors = async () => { + try { + const manualModule = await import('../data/contributors-manual.json'); + const manualData = manualModule.default as { contributors?: Array }; + const mapped = (manualData?.contributors || []).map((c: any) => { + const username: string = c?.login || c?.name || 'friend'; + const name: string = c?.name || username; + const bio: string | null = c?.bio || null; + const avatar: string | undefined = c?.avatar_url || undefined; + return { + avatar, + role: name, + thanks: bio || 'Thank you for supporting UTCP.', + username + }; + }); + setOtherContributors(mapped); + } catch (err) { + // Fallback to a small static list when manual file is unavailable + setOtherContributors([ + { avatar: undefined, role: 'Maintainer', thanks: 'Guiding the project and ensuring high quality.', username: 'maintainer' }, + { avatar: undefined, role: 'Designer', thanks: 'Improving UX and visual language.', username: 'designer' }, + { avatar: undefined, role: 'Researcher', thanks: 'Exploring the landscape and informing decisions.', username: 'researcher' } + ]); + } + }; + loadOtherContributors(); + }, []); + + const OtherContributorCard = ({ avatar, role, thanks, username }: { avatar?: string; role: string; thanks: string; username: string }) => { + const [imageError, setImageError] = useState(false); + const showImage = Boolean(avatar) && !imageError; + return ( +
+
+ {showImage ? ( + {`${role} setImageError(true)} + /> + ) : ( + {generateFallbackAvatar(username)} + )} +
+
{role}
+
{thanks}
+
+ ); + }; return ( ))} + +
+
+

Special Thanks

+

Beyond code, here are some of our champions

+
+
+ {otherContributors.map((oc, i) => ( + + ))} +
+
{contributors.length > 1 && contributors[0]?.total_changes > 0 && (