1+ <script lang="ts" setup>
2+ import { useStorage } from ' @vueuse/core'
3+
4+ const contributors = useStorage <any []>(' contributors' , [])
5+
6+ const fromRepo = (repo : string ) =>
7+ fetch (` https://api.github.com/repos/tweakphp/${repo }/contributors ` )
8+ .then ((res ) => res .json ())
9+ .catch (() => [])
10+
11+ const getContributors = async () => {
12+ const users = await Promise .all ([
13+ fromRepo (' tweakphp' ),
14+ fromRepo (' docs' ),
15+ fromRepo (' client' ),
16+ fromRepo (' .github' ),
17+ ])
18+
19+ contributors .value = users .reduce ((acc , data = []) => {
20+ if (! Array .isArray (data )) {
21+ return acc
22+ }
23+
24+ return [... acc , ... data .filter (i => i .login )]
25+ }, []).reduce ((acc , user ) => {
26+ const existingUser = acc .find (u => u .id === user .id )
27+
28+ if (existingUser ) {
29+ existingUser .contributions += user .contributions
30+ return acc
31+ }
32+
33+ return [... acc , {
34+ id: user .id ,
35+ username: user .login ,
36+ contributions: user .contributions ,
37+ avatar_url: user .avatar_url
38+ }]
39+ }, [])
40+ }
41+
42+ getContributors ()
43+ </script >
44+
45+ <template >
46+ <div class =" text-lg text-center leading-7 my-10 px-5" >
47+ <div class =" flex flex-wrap gap-2" >
48+ <a
49+ v-for =" contributor of contributors"
50+ :key =" contributor.id"
51+ v-tooltip =" contributor.username"
52+ :href =" `https://github.com/${contributor.username}`"
53+ :aria-label =" contributor.username"
54+ rel =" noopener noreferrer"
55+ target =" _blank"
56+ >
57+ <img
58+ :src =" contributor.avatar_url"
59+ :alt =" contributor.username"
60+ :aria-label =" contributor.username"
61+ loading =" lazy"
62+ width =" 50"
63+ height =" 50"
64+ class =" w-15 h-15 min-w-15 min-h-15 !rounded-full"
65+ />
66+ </a >
67+ </div >
68+ </div >
69+ </template >
0 commit comments