|
| 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> |
0 commit comments