Skip to content

Commit

Permalink
feat(community): add thank-a-contributor widget (#2055)
Browse files Browse the repository at this point in the history
  • Loading branch information
krisstern authored Jan 10, 2025
1 parent f367356 commit 71ad2a9
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 0 deletions.
2 changes: 2 additions & 0 deletions plugins/plugin-site/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"cheerio": "1.0.0",
"classnames": "2.5.1",
"copy-to-clipboard": "3.3.3",
"dayjs": "^1.11.13",
"find-package-json": "1.2.0",
"gatsby-plugin-canonical-urls": "5.14.0",
"gatsby-plugin-extract-schema": "0.2.2",
Expand All @@ -87,6 +88,7 @@
"github-syntax-light": "0.5.0",
"isomorphic-fetch": "3.0.0",
"jest-environment-jsdom": "29.7.0",
"papaparse": "^5.4.1",
"postcss-calc": "10.1.0",
"postcss-css-variables": "0.19.0",
"postcss-import": "16.1.0",
Expand Down
49 changes: 49 additions & 0 deletions plugins/plugin-site/src/components/ThankAContributorNote.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
.thank-you-note-container {
padding: 40px 16px;
display: flex;
justify-content: center;
align-items: center;
}

.thank-you-note-contents {
padding: 24px;
border-radius: 40px;
max-width: fit-content;
height: fit-content;
background-color: rgb(218, 209, 198, 0.3);
display: flex;
justify-content: center;
align-items: center;
@media (max-width: 768px) {
padding: 16px;
}
}

.thank-you-note-card {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 24px;
@media (max-width: 768px) {
gap: 8px;
}
}

.thank-you-note-img-container {
display: flex;
justify-content: center;
align-items: center;
}

.thank-you-note-img {
margin-top: auto;
margin-bottom: auto;
}

.thank-you-note-text {
font-size: medium;
@media (max-width: 768px) {
font-size: small;
}
}
151 changes: 151 additions & 0 deletions plugins/plugin-site/src/components/ThankAContributorNote.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/* eslint-disable react/jsx-one-expression-per-line */

import React, {useEffect, useState} from 'react';
import axios from 'axios';
import dayjs from 'dayjs';
import Papa from 'papaparse';
import {useMediaQuery} from '../hooks/useMediaQuery';
import './ThankAContributorNote.css';

function ThankAContributorNote() {
const isMobile = useMediaQuery('man-width: 768px)');
const isDesktop = useMediaQuery('(min-width: 1024px)');

const [thankYou, setThankYou] = useState({});

const dataUrl = 'https://raw.githubusercontent.com/jenkins-infra/jenkins-contribution-stats/main/data/honored_contributor.csv';

useEffect(() => {
axios
.get(
dataUrl,
{responseType: 'text'}
)
.then((response) => {
if (Papa.parse(response.data)?.data[1]) {
const data = Papa.parse(response.data)?.data[1];
setThankYou(Papa.parse(response.data)?.data[1] ? {
'RUN_DATE': data[0],
'MONTH': data[1],
'GH_HANDLE': data[2],
'FULL_NAME': data[3],
'COMPANY': data[4],
'GH_HANDLE_URL': data[5],
'GH_HANDLE_AVATAR': data[6],
'NBR_PRS': data[7],
'REPOSITORIES': data[8],
}: {});
}
});

const interval = setInterval(() => {
axios
.get(
dataUrl,
{responseType: 'text'}
)
.then((response) => {
if (Papa.parse(response.data)?.data[1]) {
const data = Papa.parse(response.data)?.data[1];
setThankYou(Papa.parse(response.data)?.data[1] ? {
'RUN_DATE': data[0],
'MONTH': data[1],
'GH_HANDLE': data[2],
'FULL_NAME': data[3],
'COMPANY': data[4],
'GH_HANDLE_URL': data[5],
'GH_HANDLE_AVATAR': data[6],
'NBR_PRS': data[7],
'REPOSITORIES': data[8],
}: {});
}
});
}, 3600000);

return () => clearInterval(interval);
}, []);


return (
<div
className="thank-you-note-container"
>
<div
className="thank-you-note-contents"
>
<div
className="thank-you-note-card"
>
<div
className="thank-you-note-img-container"
>
<img
src={thankYou['GH_HANDLE_AVATAR']?.replace(/['"]+/g, '')}
alt="Random contributor image"
width={isDesktop ? 100 : isMobile ? 36 : 90}
height={
isDesktop ? 100 : isMobile ? '100%' : 90
}
className="thank-you-note-img"
/>
</div>
<div
className="thank-you-note-text"
>
Thank you{' '}
{Object.values(thankYou)?.filter((item) => item?.trim() === '')
.length === 0 && (<a target="_blank" rel="noreferrer" href={thankYou['GH_HANDLE_URL']?.replace(/['"]+/g, '')}>{thankYou['FULL_NAME']?.replace(/['"]+/g, '').trim() ? thankYou['FULL_NAME']?.replace(/['"]+/g, '') : thankYou['GH_HANDLE']?.replace(/['"]+/g, '')}</a>
)}
<br/>for making {thankYou['NBR_PRS']?.replace(
/['"]+/g,
''
)} pull{' '}
{parseInt(thankYou['NBR_PRS']?.replace(/['"]+/g, '')) >= 2
? 'requests'
: 'request'}
<br/>to{' '}
{thankYou['REPOSITORIES']?.split(' ')?.length >= 4
? `${parseInt(thankYou['REPOSITORIES']?.split(' ')?.length)} Jenkins `
: 'the '}
{thankYou['REPOSITORIES']?.split(' ').length < 4 &&
thankYou['REPOSITORIES']
?.replace(/['"]+/g, '')
.split(/\s+/)
.filter(Boolean)
.map((repo, idx) => (
<>
{thankYou['REPOSITORIES']?.split(' ').length >
2 &&
idx ===
thankYou['REPOSITORIES']?.split(' ')
.length -
2 &&
' and '
}
<a
target="_blank"
rel="noreferrer"
href={`https://github.com/${repo}`}
>
{repo?.split('/')[1]}
</a>
{thankYou['REPOSITORIES']?.split(' ').length >=
2 && idx < thankYou['REPOSITORIES']?.split(' ').length - 2 ? (<>,</>) : (<>{' '}</>)}
</>
))}{' '}
{thankYou['REPOSITORIES']?.split(' ').length > 2
? 'repos'
: 'repo'}{' '}
in{' '}
{dayjs(thankYou['MONTH']?.replace(/['"]+/g, '')).format(
'MMMM YYYY'
)}
!
</div>
</div>
</div>
</div>
);
}

export default ThankAContributorNote;
19 changes: 19 additions & 0 deletions plugins/plugin-site/src/hooks/useMediaQuery.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {useEffect, useState} from 'react';

export function useMediaQuery(query) {
const [matches, setMatches] = useState(false);

useEffect(() => {
const matchQueryList = window.matchMedia(query);
function handleChange(e) {
setMatches(e.matches);
}
matchQueryList.addEventListener('change', handleChange);

return () => {
matchQueryList.removeEventListener('change', handleChange);
};
}, [query]);

return matches;
}
2 changes: 2 additions & 0 deletions plugins/plugin-site/src/templates/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import SearchBox from '../components/SearchBox';
import JenkinsVoltron from '../components/JenkinsVoltron';

import './index.css';
import ThankAContributorNote from '../components/ThankAContributorNote';


function IndexPage() {
Expand Down Expand Up @@ -36,6 +37,7 @@ function IndexPage() {
</div>
</div>
<Footer />
<ThankAContributorNote />
</Layout>
);
}
Expand Down
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4205,6 +4205,7 @@ __metadata:
cheerio: "npm:1.0.0"
classnames: "npm:2.5.1"
copy-to-clipboard: "npm:3.3.3"
dayjs: "npm:^1.11.13"
dotenv: "npm:16.4.7"
eslint: "npm:9.17.0"
eslint-config-standard: "npm:17.1.0"
Expand Down Expand Up @@ -4242,6 +4243,7 @@ __metadata:
jest-environment-jsdom: "npm:29.7.0"
jest-junit: "npm:16.0.0"
lint-staged: "npm:15.3.0"
papaparse: "npm:^5.4.1"
postcss-calc: "npm:10.1.0"
postcss-css-variables: "npm:0.19.0"
postcss-import: "npm:16.1.0"
Expand Down Expand Up @@ -9299,6 +9301,13 @@ __metadata:
languageName: node
linkType: hard

"dayjs@npm:^1.11.13":
version: 1.11.13
resolution: "dayjs@npm:1.11.13"
checksum: 10c0/a3caf6ac8363c7dade9d1ee797848ddcf25c1ace68d9fe8678ecf8ba0675825430de5d793672ec87b24a69bf04a1544b176547b2539982275d5542a7955f35b7
languageName: node
linkType: hard

"debug@npm:2, debug@npm:2.6.9, debug@npm:^2.6.0":
version: 2.6.9
resolution: "debug@npm:2.6.9"
Expand Down Expand Up @@ -17624,6 +17633,13 @@ __metadata:
languageName: node
linkType: hard

"papaparse@npm:^5.4.1":
version: 5.4.1
resolution: "papaparse@npm:5.4.1"
checksum: 10c0/201f37c4813453fed5bfb4c01816696b099d2db9ff1e8fb610acc4771fdde91d2a22b6094721edb0fedb21ca3c46f04263f68be4beb3e35b8c72278f0cedc7b7
languageName: node
linkType: hard

"param-case@npm:^3.0.4":
version: 3.0.4
resolution: "param-case@npm:3.0.4"
Expand Down

0 comments on commit 71ad2a9

Please sign in to comment.