step 1: hard-code data, cleanup code and urls

This commit is contained in:
martin-mfg
2025-11-16 14:04:02 +01:00
parent b7bf277b0e
commit 52049e1cbf
5 changed files with 256 additions and 90 deletions
+38 -22
View File
@@ -12,6 +12,8 @@ import 'react-loading-skeleton/dist/skeleton.css';
import { createMockReq, createMockRes } from '../../mock-http';
import { default as router } from '../../backend/.vercel/output/functions/api.func/router.js';
import axios from 'axios';
import { HOST } from '../../constants';
import { DEMO_STATS_CARD } from './demoData/statsCard';
const SvgInline = (props) => {
const [svg, setSvg] = useState(null);
@@ -26,33 +28,47 @@ const SvgInline = (props) => {
process.env.PAT_1 = userToken;
setLoaded(false);
const isAuthenticated = userId && userId.length > 0;
if (isAuthenticated && (!userToken || userToken === 'placeholderPAT')) {
// waiting for backend call to private-access
return;
}
let body;
let status;
if (isAuthenticated) {
const req = createMockReq({
method: 'GET',
url: url,
});
const res = createMockRes();
await router(req, res);
body = res._getBody();
status = res._getStatusCode();
} else {
let res = await axios.get(url);
body = res.data;
status = res.status;
switch (url) {
case `https://${HOST}/api?username=anuraghazra&include_all_commits=true&client=wizard`:
status = 200;
body = DEMO_STATS_CARD;
break;
default:
const isAuthenticated = userId && userId.length > 0;
if (
isAuthenticated &&
(!userToken || userToken === 'placeholderPAT')
) {
// waiting for backend call to private-access
return;
}
if (isAuthenticated) {
const req = createMockReq({
method: 'GET',
url: url,
});
const res = createMockRes();
await router(req, res);
body = res._getBody();
status = res._getStatusCode();
} else {
let res = await axios.get(url);
body = res.data;
status = res.status;
}
if (status >= 300) {
console.error('failed to fetch/generate SVG');
return;
}
}
if (status >= 300) {
console.error('failed to fetch/generate SVG');
return;
}
setSvg(body);
setLoaded(true);
};
@@ -0,0 +1,212 @@
export const DEMO_STATS_CARD = `
<svg
width="450"
height="195"
viewBox="0 0 450 195"
fill="none"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-labelledby="descId"
>
<title id="titleId">Anurag Hazra's GitHub Stats, Rank: S</title>
<desc id="descId">Total Stars Earned: 81043, Total Commits : 27218, Total PRs: 820, Total Issues: 180, Contributed to (last year): 1</desc>
<style>
.header {
font: 600 18px 'Segoe UI', Ubuntu, Sans-Serif;
fill: #2f80ed;
animation: fadeInAnimation 0.8s ease-in-out forwards;
}
@supports(-moz-appearance: auto) {
/* Selector detects Firefox */
.header { font-size: 15.5px; }
}
.stat {
font: 600 14px 'Segoe UI', Ubuntu, "Helvetica Neue", Sans-Serif; fill: #434d58;
}
@supports(-moz-appearance: auto) {
/* Selector detects Firefox */
.stat { font-size:12px; }
}
.stagger {
opacity: 0;
animation: fadeInAnimation 0.3s ease-in-out forwards;
}
.rank-text {
font: 800 24px 'Segoe UI', Ubuntu, Sans-Serif; fill: #434d58;
animation: scaleInAnimation 0.3s ease-in-out forwards;
}
.rank-percentile-header {
font-size: 14px;
}
.rank-percentile-text {
font-size: 16px;
}
.not_bold { font-weight: 400 }
.bold { font-weight: 700 }
.icon {
fill: #4c71f2;
display: none;
}
.rank-circle-rim {
stroke: #2f80ed;
fill: none;
stroke-width: 6;
opacity: 0.2;
}
.rank-circle {
stroke: #2f80ed;
stroke-dasharray: 250;
fill: none;
stroke-width: 6;
stroke-linecap: round;
opacity: 0.8;
transform-origin: -10px 8px;
transform: rotate(-90deg);
animation: rankAnimation 1s forwards ease-in-out;
}
@keyframes rankAnimation {
from {
stroke-dashoffset: 251.32741228718345;
}
to {
stroke-dashoffset: 0.20935681155589697;
}
}
/* Animations */
@keyframes scaleInAnimation {
from {
transform: translate(-5px, 5px) scale(0);
}
to {
transform: translate(-5px, 5px) scale(1);
}
}
@keyframes fadeInAnimation {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
</style>
<rect
data-testid="card-bg"
x="0.5"
y="0.5"
rx="4.5"
height="99%"
stroke="#e4e2e2"
width="449"
fill="#fffefe"
stroke-opacity="1"
/>
<g
data-testid="card-title"
transform="translate(25, 35)"
>
<g transform="translate(0, 0)">
<text
x="0"
y="0"
class="header"
data-testid="header"
>Anurag Hazra's GitHub Stats</text>
</g>
</g>
<g
data-testid="main-card-body"
transform="translate(0, 55)"
>
<g data-testid="rank-circle"
transform="translate(365, 47.5)">
<circle class="rank-circle-rim" cx="-10" cy="8" r="40" />
<circle class="rank-circle" cx="-10" cy="8" r="40" />
<g class="rank-text">
<text x="-5" y="3" alignment-baseline="central" dominant-baseline="central" text-anchor="middle" data-testid="level-rank-icon">
S
</text>
</g>
</g>
<svg x="0" y="0">
<g transform="translate(0, 0)">
<g class="stagger" style="animation-delay: 450ms" transform="translate(25, 0)">
<text class="stat bold" y="12.5">Total Stars Earned:</text>
<text
class="stat bold"
x="204.01"
y="12.5"
data-testid="stars"
>81k</text>
</g>
</g><g transform="translate(0, 25)">
<g class="stagger" style="animation-delay: 600ms" transform="translate(25, 0)">
<text class="stat bold" y="12.5">Total Commits:</text>
<text
class="stat bold"
x="204.01"
y="12.5"
data-testid="commits"
>27.2k</text>
</g>
</g><g transform="translate(0, 50)">
<g class="stagger" style="animation-delay: 750ms" transform="translate(25, 0)">
<text class="stat bold" y="12.5">Total PRs:</text>
<text
class="stat bold"
x="204.01"
y="12.5"
data-testid="prs"
>820</text>
</g>
</g><g transform="translate(0, 75)">
<g class="stagger" style="animation-delay: 900ms" transform="translate(25, 0)">
<text class="stat bold" y="12.5">Total Issues:</text>
<text
class="stat bold"
x="204.01"
y="12.5"
data-testid="issues"
>180</text>
</g>
</g><g transform="translate(0, 100)">
<g class="stagger" style="animation-delay: 1050ms" transform="translate(25, 0)">
<text class="stat bold" y="12.5">Contributed to (last year):</text>
<text
class="stat bold"
x="204.01"
y="12.5"
data-testid="contribs"
>1</text>
</g>
</g>
</svg>
</g>
</svg>
`;
+2 -2
View File
@@ -37,7 +37,7 @@ const HomeScreen = () => {
// for stage one
const [selectedCard, setSelectedCard] = useState('stats');
const [imageSrc, setImageSrc] = useState(`?&username=${userId}`);
const [imageSrc, setImageSrc] = useState(`?username=${userId}`);
// for stage two
const [selectedStatsRank, setSelectedStatsRank] =
@@ -89,7 +89,7 @@ const HomeScreen = () => {
}, [selectedCard]);
useEffect(() => {
setImageSrc(`?&username=${userId}`);
setImageSrc(`?username=${userId}`);
}, [userId]);
let fullSuffix = `${imageSrc}`;
@@ -30,14 +30,14 @@ const LoginStage = ({ setCurrItem }) => {
{
title: 'GitHub Stats Card',
description: 'your overall GitHub statistics',
imageSrc: `?&username=anuraghazra`,
imageSrc: '?username=anuraghazra',
demoCustomization: '&include_all_commits=true',
cardType: 'stats',
},
{
title: 'Top Languages Card',
description: 'your most frequently used languages',
imageSrc: `/top-langs?&username=anuraghazra`,
imageSrc: '/top-langs?username=anuraghazra',
demoCustomization: '&langs_count=4',
cardType: 'top-langs',
},
@@ -270,68 +270,6 @@ const LoginStage = ({ setCurrItem }) => {
</div>
</div>
);
return (
<div className="w-full flex flex-wrap">
{[
{
title: 'GitHub Stats Card',
description: 'your overall GitHub statistics',
imageSrc: `?&username=${userId}`,
demoCustomization: '&include_all_commits=true',
cardType: 'stats',
},
{
title: 'Top Languages Card',
description: 'your most frequently used languages',
imageSrc: `/top-langs?&username=${userId}`,
demoCustomization: '&langs_count=4',
cardType: 'top-langs',
},
{
title: 'GitHub Extra Pin',
description:
'pin more than 6 repositories in your profile using a GitHub profile readme',
imageSrc: '/pin?repo=anuraghazra/github-readme-stats',
demoCustomization: '',
cardType: 'pin',
},
{
title: 'GitHub Gist Pin',
description:
'pin gists in your GitHub profile using a GitHub profile readme',
imageSrc: '/gist?id=bbfce31e0217a3689c8d961a356cb10d',
demoCustomization: '',
cardType: 'gist',
},
{
title: 'WakaTime Stats Card',
description: 'your coding activity from WakaTime',
imageSrc: '/wakatime?username=ffflabs',
demoCustomization: '&langs_count=6&card_width=450',
cardType: 'wakatime',
},
].map((card, index) => (
<button
className="p-2 lg:p-4"
key={index}
type="button"
onClick={() => {
setSelectedCard(card.cardType);
setImageSrc(card.imageSrc);
}}
>
<Card
title={card.title}
description={card.description}
imageSrc={card.imageSrc + card.demoCustomization}
selected={selectedCard === card.cardType}
fixedSize="true"
/>
</button>
))}
</div>
);
};
LoginStage.propTypes = {
@@ -14,14 +14,14 @@ const SelectCardStage = ({ selectedCard, setSelectedCard, setImageSrc }) => {
{
title: 'GitHub Stats Card',
description: 'your overall GitHub statistics',
imageSrc: `?&username=${userId}`,
imageSrc: `?username=${userId}`,
demoCustomization: '&include_all_commits=true',
cardType: 'stats',
},
{
title: 'Top Languages Card',
description: 'your most frequently used languages',
imageSrc: `/top-langs?&username=${userId}`,
imageSrc: `/top-langs?username=${userId}`,
demoCustomization: '&langs_count=4',
cardType: 'top-langs',
},