Writes componenent to display detailed GitHub metrics of a given service
This commit is contained in:
parent
a6906c0058
commit
631c5283eb
|
@ -0,0 +1,282 @@
|
|||
---
|
||||
import type { GitHubStatsResponse } from '@utils/fetch-repo-info'
|
||||
import { formatDate, timeAgo } from '@utils/dates-n-stuff';
|
||||
|
||||
import FontAwesome from "@components/form/FontAwesome.svelte"
|
||||
|
||||
interface Props {
|
||||
gitHubData: GitHubStatsResponse;
|
||||
repo: string;
|
||||
}
|
||||
|
||||
const { gitHubData, repo } = Astro.props;
|
||||
|
||||
|
||||
function generateChartData(languages: Record<string, number>): string {
|
||||
|
||||
const colorMap: { [key: string]: string } = {
|
||||
'TypeScript': '#2b7489',
|
||||
'Objective-C++': '#6866fb',
|
||||
'Jupyter Notebook': '#DA5B0B',
|
||||
'Dart': '#00B4AB',
|
||||
'Shell': '#89e051',
|
||||
'Elixir': '#6e4a7e',
|
||||
'Kotlin': '#F18E33',
|
||||
'Objective-C': '#438eff',
|
||||
'Ruby': '#701516',
|
||||
'Go': '#375eab',
|
||||
'PHP': '#4F5D95',
|
||||
'Java': '#b07219',
|
||||
'Scala': '#DC322F',
|
||||
'Makefile': '#427819',
|
||||
'Perl': '#0298c3',
|
||||
'Lua': '#000080',
|
||||
'Vue': '#2c3e50',
|
||||
'HTML': '#e44b23',
|
||||
'Swift': '#ffac45',
|
||||
'C': '#555555',
|
||||
'C#': '#097c01',
|
||||
'Clojure': '#db5855',
|
||||
'Rust': '#dea584',
|
||||
'Assembly': '#6E4C13',
|
||||
'Arduino': '#bd79d1',
|
||||
'C Sharp': '#178600',
|
||||
'CSS': '#563d7c',
|
||||
'TeX': '#3D6117',
|
||||
'OCaml': '#3be133',
|
||||
'Pascal': '#b0ce4e',
|
||||
'F#': '#b845fc',
|
||||
'JavaScript': '#f1e05a',
|
||||
'VimL': '#199f4b',
|
||||
'R': '#198ce7',
|
||||
'Erlang': '#B83998',
|
||||
'Scheme': '#1e4aec',
|
||||
'Python': '#3572A5',
|
||||
'Common Lisp': '#3fb68b',
|
||||
'Groovy': '#e69f56',
|
||||
'Julia': '#a270ba',
|
||||
'cpp': '#f34b7d',
|
||||
};
|
||||
|
||||
// Arrays to hold the data, labels, and colors
|
||||
const data: number[] = [];
|
||||
const labels: string[] = [];
|
||||
const colors: string[] = [];
|
||||
|
||||
// Default colors to use if the language is not in the colorMap
|
||||
const defaultColors = ['#ffdf60', '#5f53f4', '#28dffd', '#f45397'];
|
||||
let defaultColorIndex = 0;
|
||||
|
||||
// Populate the data, labels, and colors arrays
|
||||
for (const [language, lines] of Object.entries(languages)) {
|
||||
data.push(lines);
|
||||
labels.push(language);
|
||||
|
||||
// Assign a color from the colorMap if available; otherwise, use a default color
|
||||
if (colorMap[language]) {
|
||||
colors.push(colorMap[language]);
|
||||
} else {
|
||||
colors.push(defaultColors[defaultColorIndex % defaultColors.length]);
|
||||
defaultColorIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the chart data object as a string
|
||||
const chartData = JSON.stringify({
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
datasets: [{
|
||||
data: data,
|
||||
backgroundColor: colors,
|
||||
borderWidth: 0,
|
||||
label: 'Language Usage',
|
||||
}],
|
||||
labels: labels,
|
||||
},
|
||||
options: {
|
||||
cutoutPercentage: 80,
|
||||
legend: {
|
||||
display: true,
|
||||
},
|
||||
plugins: {
|
||||
datalabels: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
aspectRatio: 1,
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
});
|
||||
|
||||
// Encode the chart data for use in a URL
|
||||
return encodeURIComponent(chartData);
|
||||
}
|
||||
|
||||
const formatBigNumber = (num: number): string => {
|
||||
if (!num) return 'None';
|
||||
return num.toLocaleString();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
const languageChart = `https://quickchart.io/chart?c=${generateChartData(gitHubData.languages)}`;
|
||||
|
||||
|
||||
---
|
||||
|
||||
<div class="gh-info-wrap">
|
||||
|
||||
<div class="left">
|
||||
<h4>Author</h4>
|
||||
<p>
|
||||
<img src={gitHubData.info.ownerAvatar} width="20" height="20" />
|
||||
<a href={`https://github.com/${gitHubData.info.ownerUsername}`}>
|
||||
{gitHubData.info.ownerUsername}
|
||||
</a>
|
||||
</p>
|
||||
<h4>Description</h4>
|
||||
<p>
|
||||
{gitHubData.info.description}
|
||||
</p>
|
||||
<span class="tags">
|
||||
{gitHubData.info.topics.map((topic) => (
|
||||
<span class="tag">#{topic}</span>
|
||||
))}
|
||||
</span>
|
||||
<h4>Homepage</h4>
|
||||
<a href={gitHubData.info.homepage}>{gitHubData.info.homepage}</a>
|
||||
<h4>License</h4>
|
||||
<p>{gitHubData.info.license}</p>
|
||||
<h4>Created</h4>
|
||||
<p title={timeAgo(gitHubData.info.createdAt)}>{formatDate(gitHubData.info.createdAt)}</p>
|
||||
<h4>Last Updated</h4>
|
||||
<p title={timeAgo(gitHubData.info.updatedAt)}>{formatDate(gitHubData.info.updatedAt)}</p>
|
||||
{ gitHubData.versions.length > 0 && (
|
||||
<h4>Latest version</h4>
|
||||
<p title={gitHubData.versions[0].commit}>
|
||||
{gitHubData.versions[0].name}
|
||||
<a href={gitHubData.versions[0].zipball}><FontAwesome iconName="download" /></a>
|
||||
</p>
|
||||
)}
|
||||
<h4>Primary Language</h4>
|
||||
<p>{gitHubData.info.language}</p>
|
||||
<h4>Size</h4>
|
||||
<p>{formatBigNumber(gitHubData.info.size)} KB</p>
|
||||
<h4>Stars</h4>
|
||||
<p>{formatBigNumber(gitHubData.info.scarCount)}</p>
|
||||
<h4>Forks</h4>
|
||||
<p>{formatBigNumber(gitHubData.info.forksCount)}</p>
|
||||
<h4>Watchers</h4>
|
||||
<p>{formatBigNumber(gitHubData.info.watchersCount)}</p>
|
||||
|
||||
</div>
|
||||
<div class="right">
|
||||
<h4>Language Usage</h4>
|
||||
<img class="languages-img" width="600" src={languageChart} alt="Language Usage" />
|
||||
<h4>Star History</h4>
|
||||
<img class="languages-img" width="600" src={`https://api.star-history.com/svg?repos=${repo}&type=Date`} alt="Star History" />
|
||||
</div>
|
||||
<div class="long-list-data">
|
||||
<div class="left list-wrap">
|
||||
<h4>Top Contributors</h4>
|
||||
<ul>
|
||||
{gitHubData.contributors.map((contributor) => (
|
||||
<li>
|
||||
<img src={contributor.avatar} width="20" height="20" />
|
||||
<a href={`https://github.com/${contributor.username}`}>@{contributor.username}</a> ({contributor.contributions})
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right list-wrap">
|
||||
<h4>Recent Commits</h4>
|
||||
<ul>
|
||||
{gitHubData.commits.map((commit) => (
|
||||
<li>
|
||||
<img src={commit.authorAvatar} width="20" height="20" />
|
||||
<a href={`https://github.com/${commit.authorUsername}`}>{commit.authorName}</a>
|
||||
<span class="date" title={timeAgo(commit.authorDate)}>({formatDate(commit.authorDate)})</span>
|
||||
<p class="commit-msg">{commit.message}</p>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.gh-info-wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
.left, .right {
|
||||
width: 50%;
|
||||
@media (max-width: 768px) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.long-list-data {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
.list-wrap {
|
||||
.date {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.commit-msg {
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.8;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 1rem 0 0 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
p {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.25rem;
|
||||
:global(svg) {
|
||||
width: 1rem;
|
||||
}
|
||||
img {
|
||||
border-radius: var(--curve-sm);
|
||||
}
|
||||
}
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.tag {
|
||||
margin: 0.1rem;
|
||||
background: #5f53f440;
|
||||
border-radius: var(--curve-sm);
|
||||
padding: 0.05rem 0.2rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
ul {
|
||||
padding-left: 1rem;
|
||||
list-style: circle;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
img {
|
||||
border-radius: var(--curve-sm);
|
||||
}
|
||||
}
|
||||
.languages-img {
|
||||
width: 100%;
|
||||
border-radius: var(--curve-sm);
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue