js • Lines: 104'use client';
import { forwardRef, useState, useCallback, useEffect } from 'react';
import { ActivityCalendar } from 'react-activity-calendar';
import { jsx } from 'react/jsx-runtime';
const gitHubTheme = {
light: ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39'],
dark: ['#161b22', '#0e4429', '#006d32', '#26a641', '#39d353']
};
const transformData = (data, transformFn) => {
if (typeof transformFn !== 'function') {
return data;
}
const transformedData = transformFn(data);
if (!Array.isArray(transformedData)) {
throw Error(`transformData() function must return a list of Activity objects.`);
}
for (const d of transformedData) {
if (!isRecord(d)) {
throw Error(`transformData() must return a list of valid Activity objects.`);
}
if (typeof d.count !== 'number' || d.count < 0) {
throw Error(`Required property "count: number" missing or invalid. Got: ${d.count}`);
}
if (typeof d.date !== 'string' || !/\d{4}-\d{2}-\d{2}/.test(d.date)) {
throw Error(`Required property "date: YYYY-MM-DD" missing or invalid. Got: ${d.date}`);
}
if (typeof d.level !== 'number' || d.level < 0 || d.level > 4) {
throw Error(`Required property "level: 0 | 1 | 2 | 3 | 4" missing or invalid: Got: ${d.level}.`);
}
}
return transformedData;
};
const isRecord = o => Object.prototype.toString.call(o) === '[object Object]';
async function fetchCalendarData(username, year) {
const apiUrl = 'https://github-contributions-api.jogruber.de/v4/';
const response = await fetch(`${apiUrl}${username}?y=${String(year)}`);
const data = await response.json();
if (!response.ok) {
throw Error(`Fetching GitHub contribution data for "${username}" failed: ${data.error}`);
}
return data;
}
const GitHubCalendar = /*#__PURE__*/forwardRef(({
username,
year = 'last',
labels,
transformData: transformFn,
throwOnError = false,
errorMessage = `Error – Fetching GitHub contribution data for "${username}" failed.`,
...props
}, ref) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchData = useCallback(() => {
setLoading(true);
setError(null);
fetchCalendarData(username, year).then(setData).catch(err => {
if (err instanceof Error) {
setError(err);
}
}).finally(() => {
setLoading(false);
});
}, [username, year]);
useEffect(fetchData, [fetchData]);
// React error boundaries can't handle asynchronous code, so rethrow.
if (error) {
if (throwOnError) {
throw error;
} else {
return /*#__PURE__*/jsx("div", {
children: errorMessage
});
}
}
if (loading || !data) {
return /*#__PURE__*/jsx(ActivityCalendar, {
...props,
data: [],
loading: true
});
}
const theme = props.theme ?? gitHubTheme;
const defaultLabels = {
totalCount: `{{count}} contributions in ${year === 'last' ? 'the last year' : '{{year}}'}`
};
return /*#__PURE__*/jsx(ActivityCalendar, {
data: transformData(data.contributions, transformFn),
labels: Object.assign({}, defaultLabels, labels),
ref: ref,
...props,
theme: theme,
loading: Boolean(props.loading) || loading,
maxLevel: 4
});
});
GitHubCalendar.displayName = 'GitHubCalendar';
export { GitHubCalendar };
//# sourceMappingURL=index.js.map