Skip to content

Commit 3774658

Browse files
committed
Add GitHub stars counter
1 parent 8c482ee commit 3774658

6 files changed

Lines changed: 118 additions & 4 deletions

File tree

.vitepress/config.mts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,6 @@ export default defineConfig({
109109
themeConfig: {
110110
logo: '/logo.svg',
111111

112-
socialLinks: [
113-
{ icon: 'github', link: 'https://github.com/php-testo/testo' },
114-
],
115-
116112
search: {
117113
provider: 'local',
118114
},

.vitepress/theme/GitHubStars.vue

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<script setup lang="ts">
2+
import { ref, onMounted } from 'vue'
3+
4+
const stars = ref<number | null>(null)
5+
const loading = ref(true)
6+
7+
onMounted(async () => {
8+
try {
9+
const response = await fetch('https://api.github.com/repos/php-testo/testo')
10+
const data = await response.json()
11+
stars.value = data.stargazers_count
12+
} catch (error) {
13+
console.error('Failed to fetch GitHub stars:', error)
14+
} finally {
15+
loading.value = false
16+
}
17+
})
18+
19+
const formatStars = (count: number | null) => {
20+
if (!count) return '0'
21+
if (count >= 1000) {
22+
return (count / 1000).toFixed(1) + 'k'
23+
}
24+
return count.toString()
25+
}
26+
</script>
27+
28+
<template>
29+
<a
30+
href="https://github.com/php-testo/testo"
31+
target="_blank"
32+
rel="noopener noreferrer"
33+
class="github-stars-button"
34+
>
35+
<svg class="github-icon" viewBox="0 0 16 16" width="16" height="16" aria-hidden="true">
36+
<path fill="currentColor" d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z"></path>
37+
</svg>
38+
<span v-if="!loading && stars !== null" class="github-count">
39+
{{ formatStars(stars) }}
40+
<span class="github-text">⭐</span>
41+
</span>
42+
<span v-else-if="loading" class="github-count loading">...</span>
43+
</a>
44+
</template>
45+
46+
<style scoped>
47+
.github-stars-button {
48+
display: inline-flex;
49+
align-items: center;
50+
gap: 6px;
51+
padding: 4px 12px;
52+
margin-left: 12px;
53+
font-size: 13px;
54+
font-weight: 500;
55+
line-height: 20px;
56+
color: var(--vp-c-text-1);
57+
background-color: var(--vp-c-bg-soft);
58+
border: 1px solid var(--vp-c-divider);
59+
border-radius: 6px;
60+
text-decoration: none;
61+
transition: all 0.2s ease;
62+
}
63+
64+
.github-stars-button:hover {
65+
background-color: var(--vp-c-bg-elv);
66+
border-color: var(--vp-c-brand-1);
67+
color: var(--vp-c-brand-1);
68+
}
69+
70+
.github-icon {
71+
flex-shrink: 0;
72+
}
73+
74+
.github-text {
75+
flex-shrink: 0;
76+
}
77+
78+
.github-count {
79+
display: inline-flex;
80+
align-items: center;
81+
justify-content: center;
82+
min-width: 20px;
83+
padding: 0 6px;
84+
font-size: 12px;
85+
font-weight: 600;
86+
line-height: 18px;
87+
color: var(--vp-c-text-2);
88+
background-color: var(--vp-c-default-soft);
89+
border-radius: 10px;
90+
}
91+
92+
.github-count.loading {
93+
color: var(--vp-c-text-3);
94+
}
95+
96+
/* Responsive: hide text on small screens */
97+
@media (max-width: 768px) {
98+
.github-text {
99+
display: none;
100+
}
101+
102+
.github-stars-button {
103+
padding: 4px 8px;
104+
}
105+
}
106+
</style>

.vitepress/theme/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { h } from 'vue'
22
import type { Theme } from 'vitepress'
33
import DefaultTheme from 'vitepress/theme'
44
import BlogSponsor from './BlogSponsor.vue'
5+
import GitHubStars from './GitHubStars.vue'
56
import './style.css'
67

78
export default {
89
extends: DefaultTheme,
910
Layout: () => {
1011
return h(DefaultTheme.Layout, null, {
1112
'doc-after': () => h(BlogSponsor),
13+
'nav-bar-content-after': () => h(GitHubStars),
1214
})
1315
},
1416
} satisfies Theme

.vitepress/theme/style.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,9 @@
220220
.sponsor-cta-link a:hover {
221221
color: var(--vp-c-brand-1);
222222
}
223+
224+
.sponsor-cta-link .separator {
225+
margin: 0 12px;
226+
color: var(--vp-c-divider);
227+
font-size: 14px;
228+
}

index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,7 @@ features:
4848
</div>
4949
<div class="sponsor-cta-link">
5050
<a href="/sponsor">Become a Sponsor</a>
51+
<span class="separator">|</span>
52+
<a href="https://github.com/php-testo/testo" target="_blank" rel="noopener">Star</a>
5153
</div>
5254
</div>

ru/index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,7 @@ features:
4848
</div>
4949
<div class="sponsor-cta-link">
5050
<a href="/ru/sponsor">Стать спонсором</a>
51+
<span class="separator">|</span>
52+
<a href="https://github.com/php-testo/testo" target="_blank" rel="noopener">Поставить звезду</a>
5153
</div>
5254
</div>

0 commit comments

Comments
 (0)