@rmdes/indiekit-endpoint-github 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -0
- package/assets/icon.svg +4 -0
- package/assets/styles.css +245 -0
- package/includes/@indiekit-endpoint-github-commits.njk +13 -0
- package/includes/@indiekit-endpoint-github-stars.njk +13 -0
- package/includes/@indiekit-endpoint-github-widget.njk +12 -0
- package/index.js +98 -0
- package/lib/controllers/activity.js +124 -0
- package/lib/controllers/commits.js +84 -0
- package/lib/controllers/contributions.js +60 -0
- package/lib/controllers/dashboard.js +138 -0
- package/lib/controllers/featured.js +116 -0
- package/lib/controllers/stars.js +84 -0
- package/lib/github-client.js +168 -0
- package/lib/utils.js +198 -0
- package/locales/en.json +38 -0
- package/package.json +51 -0
- package/views/activity.njk +22 -0
- package/views/commits.njk +21 -0
- package/views/contributions.njk +24 -0
- package/views/github.njk +155 -0
- package/views/stars.njk +26 -0
package/lib/utils.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Truncate text with ellipsis
|
|
3
|
+
* @param {string} text - Text to truncate
|
|
4
|
+
* @param {number} [maxLength] - Maximum length
|
|
5
|
+
* @returns {string} - Truncated text
|
|
6
|
+
*/
|
|
7
|
+
export function truncate(text, maxLength = 80) {
|
|
8
|
+
if (!text || text.length <= maxLength) return text || "";
|
|
9
|
+
return text.slice(0, maxLength - 1) + "…";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Extract commits from push events
|
|
14
|
+
* @param {Array} events - GitHub events
|
|
15
|
+
* @returns {Array} - Formatted commits
|
|
16
|
+
*/
|
|
17
|
+
export function extractCommits(events) {
|
|
18
|
+
if (!Array.isArray(events)) return [];
|
|
19
|
+
|
|
20
|
+
return events
|
|
21
|
+
.filter((event) => event.type === "PushEvent")
|
|
22
|
+
.flatMap((event) =>
|
|
23
|
+
(event.payload?.commits || []).map((commit) => ({
|
|
24
|
+
sha: commit.sha.slice(0, 7),
|
|
25
|
+
message: truncate(commit.message.split("\n")[0]),
|
|
26
|
+
url: `https://github.com/${event.repo.name}/commit/${commit.sha}`,
|
|
27
|
+
repo: event.repo.name,
|
|
28
|
+
repoUrl: `https://github.com/${event.repo.name}`,
|
|
29
|
+
date: event.created_at,
|
|
30
|
+
})),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extract PRs/Issues created from events
|
|
36
|
+
* @param {Array} events - GitHub events
|
|
37
|
+
* @returns {Array} - Formatted contributions
|
|
38
|
+
*/
|
|
39
|
+
export function extractContributions(events) {
|
|
40
|
+
if (!Array.isArray(events)) return [];
|
|
41
|
+
|
|
42
|
+
return events
|
|
43
|
+
.filter(
|
|
44
|
+
(event) =>
|
|
45
|
+
(event.type === "PullRequestEvent" || event.type === "IssuesEvent") &&
|
|
46
|
+
event.payload?.action === "opened",
|
|
47
|
+
)
|
|
48
|
+
.map((event) => {
|
|
49
|
+
const item = event.payload.pull_request || event.payload.issue;
|
|
50
|
+
return {
|
|
51
|
+
type: event.type === "PullRequestEvent" ? "pr" : "issue",
|
|
52
|
+
title: truncate(item?.title),
|
|
53
|
+
url: item?.html_url,
|
|
54
|
+
repo: event.repo.name,
|
|
55
|
+
repoUrl: `https://github.com/${event.repo.name}`,
|
|
56
|
+
number: item?.number,
|
|
57
|
+
date: event.created_at,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Format starred repos for display
|
|
64
|
+
* @param {Array} repos - Starred repositories
|
|
65
|
+
* @returns {Array} - Formatted repos
|
|
66
|
+
*/
|
|
67
|
+
export function formatStarred(repos) {
|
|
68
|
+
if (!Array.isArray(repos)) return [];
|
|
69
|
+
|
|
70
|
+
return repos.map((repo) => ({
|
|
71
|
+
name: repo.full_name,
|
|
72
|
+
description: truncate(repo.description, 120),
|
|
73
|
+
url: repo.html_url,
|
|
74
|
+
stars: repo.stargazers_count,
|
|
75
|
+
language: repo.language,
|
|
76
|
+
topics: repo.topics?.slice(0, 5) || [],
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Format user's own repositories for display
|
|
82
|
+
* @param {Array} repos - User repositories
|
|
83
|
+
* @returns {Array} - Formatted repos
|
|
84
|
+
*/
|
|
85
|
+
export function formatRepos(repos) {
|
|
86
|
+
if (!Array.isArray(repos)) return [];
|
|
87
|
+
|
|
88
|
+
return repos.map((repo) => ({
|
|
89
|
+
name: repo.name,
|
|
90
|
+
fullName: repo.full_name,
|
|
91
|
+
description: truncate(repo.description, 120),
|
|
92
|
+
url: repo.html_url,
|
|
93
|
+
stars: repo.stargazers_count,
|
|
94
|
+
forks: repo.forks_count,
|
|
95
|
+
language: repo.language,
|
|
96
|
+
topics: repo.topics?.slice(0, 5) || [],
|
|
97
|
+
isPrivate: repo.private,
|
|
98
|
+
isFork: repo.fork,
|
|
99
|
+
pushedAt: repo.pushed_at,
|
|
100
|
+
updatedAt: repo.updated_at,
|
|
101
|
+
}));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Extract activity on user's repos from other users
|
|
106
|
+
* @param {Array} events - Repository events
|
|
107
|
+
* @param {string} username - Owner username to exclude
|
|
108
|
+
* @returns {Array} - Formatted activity
|
|
109
|
+
*/
|
|
110
|
+
export function extractRepoActivity(events, username) {
|
|
111
|
+
if (!Array.isArray(events)) return [];
|
|
112
|
+
|
|
113
|
+
return events
|
|
114
|
+
.filter((event) => event.actor?.login !== username) // Exclude own activity
|
|
115
|
+
.map((event) => ({
|
|
116
|
+
type: event.type.replace("Event", "").toLowerCase(),
|
|
117
|
+
actor: event.actor?.login,
|
|
118
|
+
actorUrl: `https://github.com/${event.actor?.login}`,
|
|
119
|
+
actorAvatar: event.actor?.avatar_url,
|
|
120
|
+
repo: event.repo?.name,
|
|
121
|
+
repoUrl: `https://github.com/${event.repo?.name}`,
|
|
122
|
+
date: event.created_at,
|
|
123
|
+
detail: getEventDetail(event),
|
|
124
|
+
}));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get human-readable detail for an event
|
|
129
|
+
* @param {object} event - GitHub event
|
|
130
|
+
* @returns {string} - Event description
|
|
131
|
+
*/
|
|
132
|
+
function getEventDetail(event) {
|
|
133
|
+
switch (event.type) {
|
|
134
|
+
case "WatchEvent": {
|
|
135
|
+
return "starred";
|
|
136
|
+
}
|
|
137
|
+
case "ForkEvent": {
|
|
138
|
+
return "forked";
|
|
139
|
+
}
|
|
140
|
+
case "PullRequestEvent": {
|
|
141
|
+
return `${event.payload?.action} PR #${event.payload?.number}`;
|
|
142
|
+
}
|
|
143
|
+
case "IssuesEvent": {
|
|
144
|
+
return `${event.payload?.action} issue #${event.payload?.number}`;
|
|
145
|
+
}
|
|
146
|
+
case "IssueCommentEvent": {
|
|
147
|
+
return "commented";
|
|
148
|
+
}
|
|
149
|
+
case "CreateEvent": {
|
|
150
|
+
return `created ${event.payload?.ref_type}`;
|
|
151
|
+
}
|
|
152
|
+
case "DeleteEvent": {
|
|
153
|
+
return `deleted ${event.payload?.ref_type}`;
|
|
154
|
+
}
|
|
155
|
+
case "PushEvent": {
|
|
156
|
+
return `pushed ${event.payload?.size} commit(s)`;
|
|
157
|
+
}
|
|
158
|
+
default: {
|
|
159
|
+
return event.type?.replace("Event", "").toLowerCase() || "activity";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Format date for display
|
|
166
|
+
* @param {string} dateString - ISO date string
|
|
167
|
+
* @param {string} [locale] - Locale for formatting
|
|
168
|
+
* @returns {string} - Formatted date
|
|
169
|
+
*/
|
|
170
|
+
export function formatDate(dateString, locale = "en") {
|
|
171
|
+
const date = new Date(dateString);
|
|
172
|
+
return date.toLocaleDateString(locale, {
|
|
173
|
+
year: "numeric",
|
|
174
|
+
month: "short",
|
|
175
|
+
day: "numeric",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Format relative time
|
|
181
|
+
* @param {string} dateString - ISO date string
|
|
182
|
+
* @returns {string} - Relative time string
|
|
183
|
+
*/
|
|
184
|
+
export function formatRelativeTime(dateString) {
|
|
185
|
+
const date = new Date(dateString);
|
|
186
|
+
const now = new Date();
|
|
187
|
+
const diffMs = now - date;
|
|
188
|
+
const diffMins = Math.floor(diffMs / 60_000);
|
|
189
|
+
const diffHours = Math.floor(diffMs / 3_600_000);
|
|
190
|
+
const diffDays = Math.floor(diffMs / 86_400_000);
|
|
191
|
+
|
|
192
|
+
if (diffMins < 1) return "just now";
|
|
193
|
+
if (diffMins < 60) return `${diffMins}m ago`;
|
|
194
|
+
if (diffHours < 24) return `${diffHours}h ago`;
|
|
195
|
+
if (diffDays < 7) return `${diffDays}d ago`;
|
|
196
|
+
|
|
197
|
+
return formatDate(dateString);
|
|
198
|
+
}
|
package/locales/en.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"github": {
|
|
3
|
+
"title": "GitHub",
|
|
4
|
+
"activity": "GitHub activity",
|
|
5
|
+
"viewAll": "View all",
|
|
6
|
+
"error": {
|
|
7
|
+
"noUsername": "No GitHub username configured. Add a username in your Indiekit configuration."
|
|
8
|
+
},
|
|
9
|
+
"featured": {
|
|
10
|
+
"title": "Featured Projects",
|
|
11
|
+
"none": "No featured repositories configured"
|
|
12
|
+
},
|
|
13
|
+
"commits": {
|
|
14
|
+
"title": "Recent commits",
|
|
15
|
+
"none": "No recent commits"
|
|
16
|
+
},
|
|
17
|
+
"stars": {
|
|
18
|
+
"title": "Recently starred",
|
|
19
|
+
"none": "No starred repositories"
|
|
20
|
+
},
|
|
21
|
+
"contributions": {
|
|
22
|
+
"title": "PRs & Issues",
|
|
23
|
+
"none": "No recent contributions"
|
|
24
|
+
},
|
|
25
|
+
"repos": {
|
|
26
|
+
"title": "My repositories",
|
|
27
|
+
"none": "No repositories found"
|
|
28
|
+
},
|
|
29
|
+
"activity": {
|
|
30
|
+
"title": "Activity on my repos",
|
|
31
|
+
"none": "No recent activity from others"
|
|
32
|
+
},
|
|
33
|
+
"widget": {
|
|
34
|
+
"description": "View your GitHub activity, commits, stars, and contributions.",
|
|
35
|
+
"view": "View activity"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rmdes/indiekit-endpoint-github",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "GitHub activity endpoint for Indiekit. Display commits, stars, contributions, and featured repositories.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"indiekit",
|
|
7
|
+
"indiekit-plugin",
|
|
8
|
+
"indieweb",
|
|
9
|
+
"github",
|
|
10
|
+
"activity"
|
|
11
|
+
],
|
|
12
|
+
"homepage": "https://github.com/rmdes/indiekit-endpoint-github",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/rmdes/indiekit-endpoint-github/issues"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/rmdes/indiekit-endpoint-github.git"
|
|
19
|
+
},
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "Ricardo Mendes",
|
|
22
|
+
"url": "https://rmendes.net"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20"
|
|
27
|
+
},
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "index.js",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": "./index.js"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"assets",
|
|
35
|
+
"includes",
|
|
36
|
+
"lib",
|
|
37
|
+
"locales",
|
|
38
|
+
"views",
|
|
39
|
+
"index.js"
|
|
40
|
+
],
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@indiekit/error": "^1.0.0-beta.25",
|
|
43
|
+
"express": "^5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"peerDependencies": {
|
|
46
|
+
"@indiekit/indiekit": ">=1.0.0-beta.25"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{% extends "document.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{% if error %}
|
|
5
|
+
{{ prose({ text: error.message }) }}
|
|
6
|
+
{% elif activity and activity.length > 0 %}
|
|
7
|
+
<ul class="github-list">
|
|
8
|
+
{% for item in activity %}
|
|
9
|
+
<li class="github-list__item github-activity">
|
|
10
|
+
<img src="{{ item.actorAvatar }}" alt="{{ item.actor }}" class="github-activity__avatar" width="32" height="32">
|
|
11
|
+
<div class="github-activity__content">
|
|
12
|
+
<a href="{{ item.actorUrl }}" target="_blank" rel="noopener">{{ item.actor }}</a>
|
|
13
|
+
<span class="github-activity__detail">{{ item.detail }}</span>
|
|
14
|
+
<a href="{{ item.repoUrl }}" target="_blank" rel="noopener">{{ item.repo }}</a>
|
|
15
|
+
</div>
|
|
16
|
+
</li>
|
|
17
|
+
{% endfor %}
|
|
18
|
+
</ul>
|
|
19
|
+
{% else %}
|
|
20
|
+
{{ prose({ text: __("github.activity.none") }) }}
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% endblock %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{% extends "document.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{% if error %}
|
|
5
|
+
{{ prose({ text: error.message }) }}
|
|
6
|
+
{% elif commits and commits.length > 0 %}
|
|
7
|
+
<ul class="github-list">
|
|
8
|
+
{% for commit in commits %}
|
|
9
|
+
<li class="github-list__item">
|
|
10
|
+
<code class="github-sha"><a href="{{ commit.url }}" target="_blank" rel="noopener">{{ commit.sha }}</a></code>
|
|
11
|
+
<span class="github-commit__message">{{ commit.message }}</span>
|
|
12
|
+
<small class="github-meta">
|
|
13
|
+
<a href="{{ commit.repoUrl }}" target="_blank" rel="noopener">{{ commit.repo }}</a>
|
|
14
|
+
</small>
|
|
15
|
+
</li>
|
|
16
|
+
{% endfor %}
|
|
17
|
+
</ul>
|
|
18
|
+
{% else %}
|
|
19
|
+
{{ prose({ text: __("github.commits.none") }) }}
|
|
20
|
+
{% endif %}
|
|
21
|
+
{% endblock %}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{% extends "document.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{% if error %}
|
|
5
|
+
{{ prose({ text: error.message }) }}
|
|
6
|
+
{% elif contributions and contributions.length > 0 %}
|
|
7
|
+
<ul class="github-list">
|
|
8
|
+
{% for item in contributions %}
|
|
9
|
+
<li class="github-list__item">
|
|
10
|
+
{{ badge({
|
|
11
|
+
color: "green" if item.type === "pr" else "blue",
|
|
12
|
+
text: "PR" if item.type === "pr" else "Issue"
|
|
13
|
+
}) }}
|
|
14
|
+
<a href="{{ item.url }}" target="_blank" rel="noopener">{{ item.title }}</a>
|
|
15
|
+
<small class="github-meta">
|
|
16
|
+
<a href="{{ item.repoUrl }}" target="_blank" rel="noopener">{{ item.repo }}#{{ item.number }}</a>
|
|
17
|
+
</small>
|
|
18
|
+
</li>
|
|
19
|
+
{% endfor %}
|
|
20
|
+
</ul>
|
|
21
|
+
{% else %}
|
|
22
|
+
{{ prose({ text: __("github.contributions.none") }) }}
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% endblock %}
|
package/views/github.njk
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
{% extends "document.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{% if error %}
|
|
5
|
+
{{ prose({ text: error.message }) }}
|
|
6
|
+
{% else %}
|
|
7
|
+
{# Featured Projects #}
|
|
8
|
+
{% if featured and featured.length > 0 %}
|
|
9
|
+
<section class="github-section">
|
|
10
|
+
<h2>{{ __("github.featured.title") }}</h2>
|
|
11
|
+
<div class="github-featured">
|
|
12
|
+
{% for repo in featured %}
|
|
13
|
+
<article class="github-featured__repo">
|
|
14
|
+
<h3 class="github-featured__name">
|
|
15
|
+
<a href="{{ repo.url }}" target="_blank" rel="noopener">{{ repo.fullName }}</a>
|
|
16
|
+
{% if repo.isPrivate %}
|
|
17
|
+
{{ badge({ color: "blue", text: "Private" }) }}
|
|
18
|
+
{% endif %}
|
|
19
|
+
</h3>
|
|
20
|
+
{% if repo.description %}
|
|
21
|
+
<p class="github-featured__desc">{{ repo.description }}</p>
|
|
22
|
+
{% endif %}
|
|
23
|
+
<div class="github-featured__meta">
|
|
24
|
+
{% if repo.language %}
|
|
25
|
+
<span class="github-lang">{{ repo.language }}</span>
|
|
26
|
+
{% endif %}
|
|
27
|
+
<span>{{ repo.stars }} stars</span>
|
|
28
|
+
{% if repo.forks > 0 %}
|
|
29
|
+
<span>{{ repo.forks }} forks</span>
|
|
30
|
+
{% endif %}
|
|
31
|
+
</div>
|
|
32
|
+
{% if repo.commits and repo.commits.length > 0 %}
|
|
33
|
+
<details class="github-featured__commits">
|
|
34
|
+
<summary>Recent commits ({{ repo.commits.length }})</summary>
|
|
35
|
+
<ul class="github-commit-list">
|
|
36
|
+
{% for commit in repo.commits %}
|
|
37
|
+
<li>
|
|
38
|
+
<code><a href="{{ commit.url }}" target="_blank" rel="noopener">{{ commit.sha }}</a></code>
|
|
39
|
+
<span>{{ commit.message }}</span>
|
|
40
|
+
<small>by {{ commit.author }}</small>
|
|
41
|
+
</li>
|
|
42
|
+
{% endfor %}
|
|
43
|
+
</ul>
|
|
44
|
+
</details>
|
|
45
|
+
{% endif %}
|
|
46
|
+
</article>
|
|
47
|
+
{% endfor %}
|
|
48
|
+
</div>
|
|
49
|
+
</section>
|
|
50
|
+
{% endif %}
|
|
51
|
+
|
|
52
|
+
{# Recent Commits #}
|
|
53
|
+
<section class="github-section">
|
|
54
|
+
<h2>{{ __("github.commits.title") }}</h2>
|
|
55
|
+
{% if commits and commits.length > 0 %}
|
|
56
|
+
<ul class="github-list">
|
|
57
|
+
{% for commit in commits %}
|
|
58
|
+
<li class="github-list__item">
|
|
59
|
+
<code class="github-sha"><a href="{{ commit.url }}" target="_blank" rel="noopener">{{ commit.sha }}</a></code>
|
|
60
|
+
<span class="github-commit__message">{{ commit.message }}</span>
|
|
61
|
+
<small class="github-meta">
|
|
62
|
+
<a href="{{ commit.repoUrl }}" target="_blank" rel="noopener">{{ commit.repo }}</a>
|
|
63
|
+
</small>
|
|
64
|
+
</li>
|
|
65
|
+
{% endfor %}
|
|
66
|
+
</ul>
|
|
67
|
+
{% else %}
|
|
68
|
+
{{ prose({ text: __("github.commits.none") }) }}
|
|
69
|
+
{% endif %}
|
|
70
|
+
</section>
|
|
71
|
+
|
|
72
|
+
{# Recently Starred #}
|
|
73
|
+
<section class="github-section">
|
|
74
|
+
<h2>{{ __("github.stars.title") }}</h2>
|
|
75
|
+
{% if stars and stars.length > 0 %}
|
|
76
|
+
<ul class="github-list github-list--grid">
|
|
77
|
+
{% for star in stars %}
|
|
78
|
+
<li class="github-list__item github-star">
|
|
79
|
+
<a href="{{ star.url }}" class="github-star__name" target="_blank" rel="noopener">{{ star.name }}</a>
|
|
80
|
+
{% if star.description %}
|
|
81
|
+
<p class="github-star__desc">{{ star.description }}</p>
|
|
82
|
+
{% endif %}
|
|
83
|
+
<small class="github-meta">
|
|
84
|
+
{% if star.language %}
|
|
85
|
+
<span class="github-lang">{{ star.language }}</span>
|
|
86
|
+
{% endif %}
|
|
87
|
+
<span class="github-star__count">{{ star.stars }} stars</span>
|
|
88
|
+
</small>
|
|
89
|
+
</li>
|
|
90
|
+
{% endfor %}
|
|
91
|
+
</ul>
|
|
92
|
+
{% else %}
|
|
93
|
+
{{ prose({ text: __("github.stars.none") }) }}
|
|
94
|
+
{% endif %}
|
|
95
|
+
</section>
|
|
96
|
+
|
|
97
|
+
{# PRs & Issues #}
|
|
98
|
+
{% if contributions and contributions.length > 0 %}
|
|
99
|
+
<section class="github-section">
|
|
100
|
+
<h2>{{ __("github.contributions.title") }}</h2>
|
|
101
|
+
<ul class="github-list">
|
|
102
|
+
{% for item in contributions %}
|
|
103
|
+
<li class="github-list__item">
|
|
104
|
+
{% if item.type == "pr" %}
|
|
105
|
+
{{ badge({ color: "green", text: "PR" }) }}
|
|
106
|
+
{% else %}
|
|
107
|
+
{{ badge({ color: "purple", text: "Issue" }) }}
|
|
108
|
+
{% endif %}
|
|
109
|
+
<a href="{{ item.url }}" target="_blank" rel="noopener">{{ item.title }}</a>
|
|
110
|
+
<small class="github-meta">
|
|
111
|
+
<a href="{{ item.repoUrl }}" target="_blank" rel="noopener">{{ item.repo }}#{{ item.number }}</a>
|
|
112
|
+
</small>
|
|
113
|
+
</li>
|
|
114
|
+
{% endfor %}
|
|
115
|
+
</ul>
|
|
116
|
+
</section>
|
|
117
|
+
{% endif %}
|
|
118
|
+
|
|
119
|
+
{# My Repositories #}
|
|
120
|
+
<section class="github-section">
|
|
121
|
+
<h2>{{ __("github.repos.title") }}</h2>
|
|
122
|
+
{% if repositories and repositories.length > 0 %}
|
|
123
|
+
<ul class="github-list github-list--grid">
|
|
124
|
+
{% for repo in repositories %}
|
|
125
|
+
<li class="github-list__item github-repo">
|
|
126
|
+
<a href="{{ repo.url }}" class="github-repo__name" target="_blank" rel="noopener">
|
|
127
|
+
{{ repo.name }}
|
|
128
|
+
</a>
|
|
129
|
+
{% if repo.isPrivate %}
|
|
130
|
+
{{ badge({ color: "gray", text: "Private" }) }}
|
|
131
|
+
{% endif %}
|
|
132
|
+
{% if repo.isFork %}
|
|
133
|
+
{{ badge({ color: "purple", text: "Fork" }) }}
|
|
134
|
+
{% endif %}
|
|
135
|
+
{% if repo.description %}
|
|
136
|
+
<p class="github-repo__desc">{{ repo.description }}</p>
|
|
137
|
+
{% endif %}
|
|
138
|
+
<small class="github-meta">
|
|
139
|
+
{% if repo.language %}
|
|
140
|
+
<span class="github-lang">{{ repo.language }}</span>
|
|
141
|
+
{% endif %}
|
|
142
|
+
<span class="github-repo__stars">{{ repo.stars }} stars</span>
|
|
143
|
+
{% if repo.forks > 0 %}
|
|
144
|
+
<span class="github-repo__forks">{{ repo.forks }} forks</span>
|
|
145
|
+
{% endif %}
|
|
146
|
+
</small>
|
|
147
|
+
</li>
|
|
148
|
+
{% endfor %}
|
|
149
|
+
</ul>
|
|
150
|
+
{% else %}
|
|
151
|
+
{{ prose({ text: __("github.repos.none") }) }}
|
|
152
|
+
{% endif %}
|
|
153
|
+
</section>
|
|
154
|
+
{% endif %}
|
|
155
|
+
{% endblock %}
|
package/views/stars.njk
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{% extends "document.njk" %}
|
|
2
|
+
|
|
3
|
+
{% block content %}
|
|
4
|
+
{% if error %}
|
|
5
|
+
{{ prose({ text: error.message }) }}
|
|
6
|
+
{% elif stars and stars.length > 0 %}
|
|
7
|
+
<ul class="github-list github-list--grid">
|
|
8
|
+
{% for star in stars %}
|
|
9
|
+
<li class="github-list__item github-star">
|
|
10
|
+
<a href="{{ star.url }}" class="github-star__name" target="_blank" rel="noopener">{{ star.name }}</a>
|
|
11
|
+
{% if star.description %}
|
|
12
|
+
<p class="github-star__desc">{{ star.description }}</p>
|
|
13
|
+
{% endif %}
|
|
14
|
+
<small class="github-meta">
|
|
15
|
+
{% if star.language %}
|
|
16
|
+
<span class="github-lang">{{ star.language }}</span>
|
|
17
|
+
{% endif %}
|
|
18
|
+
<span class="github-star__count">{{ star.stars }} stars</span>
|
|
19
|
+
</small>
|
|
20
|
+
</li>
|
|
21
|
+
{% endfor %}
|
|
22
|
+
</ul>
|
|
23
|
+
{% else %}
|
|
24
|
+
{{ prose({ text: __("github.stars.none") }) }}
|
|
25
|
+
{% endif %}
|
|
26
|
+
{% endblock %}
|