Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 45 additions & 3 deletions app/pages/about.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,59 @@ const { data: contributors, status: contributorsStatus } = useLazyFetch('/api/co
</div>

<div>
<h2 class="text-lg text-fg-subtle uppercase tracking-wider mb-4">
<h2 class="text-lg text-fg-subtle uppercase tracking-wider mb-4">Team</h2>
<p class="text-fg-muted leading-relaxed mb-6">
{{ $t('about.contributors.description') }}
</p>

<!-- TODO: update string and maintainers list -->
<div v-if="contributors?.some(c => c.role !== 'contributor')" class="mb-12">
<h3 class="text-sm text-fg-subtle uppercase tracking-wider mb-4">Governance</h3>
<p class="text-fg-muted leading-relaxed mb-6">
TODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
</p>
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3">
<a
v-for="person in contributors
.filter(c => c.role !== 'contributor')
.concat(contributors.filter(c => c.role !== 'contributor'))
.concat(contributors.filter(c => c.role !== 'contributor'))
.concat(contributors.filter(c => c.role !== 'contributor'))
.concat(contributors.filter(c => c.role !== 'contributor'))"
:key="person.id"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
:href="person.html_url"
target="_blank"
rel="noopener noreferrer"
class="flex items-center gap-3 p-2 border border-border rounded-lg hover:bg-fg/5 transition-colors group"
>
<img
:src="`${person.avatar_url}&s=64`"
alt=""
class="w-10 h-10 rounded-md ring-1 ring-border group-hover:ring-accent"
/>
<div class="min-w-0">
<div class="font-mono text-sm text-fg truncate">@{{ person.login }}</div>
<div class="text-sm text-fg-muted tracking-tight">{{ person.role }}</div>
</div>
</a>
TODO: add other maintainers
</div>
</div>

<h3 class="text-sm text-fg-subtle uppercase tracking-wider mb-4">
{{
$t(
'about.contributors.title',
{ count: $n(contributors?.length ?? 0) },
contributors?.length ?? 0,
)
}}
</h2>
</h3>
<p class="text-fg-muted leading-relaxed mb-6">
{{ $t('about.contributors.description') }}
TODO: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
</p>

<!-- Contributors cloud -->
Expand Down
31 changes: 29 additions & 2 deletions server/api/contributors.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ export interface GitHubContributor {
avatar_url: string
html_url: string
contributions: number
role: Role
}

// TODO: stub - need to fetch list of role members from somewhere to avoid hardcoding (
type Role = 'stewards' | 'core' | 'maintainers' | 'contributor'
const roleMembers: Record<Exclude<Role, 'contributor'>, Set<GitHubContributor['login']>> = {
stewards: new Set(['danielroe', 'patak-dev']),
core: new Set([]),
maintainers: new Set([]),
}

function getRoleInfo(login: string): { role: Role; order: number } {
if (roleMembers.stewards.has(login)) return { role: 'stewards', order: 0 }
if (roleMembers.core.has(login)) return { role: 'core', order: 1 }
if (roleMembers.maintainers.has(login)) return { role: 'maintainers', order: 2 }
return { role: 'contributor', order: 3 }
}

export default defineCachedEventHandler(
Expand Down Expand Up @@ -46,8 +62,19 @@ export default defineCachedEventHandler(
page++
}

// Filter out bots
return allContributors.filter(c => !c.login.includes('[bot]'))
return (
allContributors
// Filter out bots
.filter(c => !c.login.includes('[bot]'))
// Assign role
.map(c => {
const { role, order } = getRoleInfo(c.login)
return Object.assign(c, { role, order })
})
// Sort by role (steward > core > maintainer > contributor)
.sort((a, b) => a.order - b.order)
.map(({ order: _, ...rest }) => rest)
)
},
{
maxAge: 3600, // Cache for 1 hour
Expand Down
Loading