mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
The commits section read numbers that were typed into scripts/sync-oss.ts (5,420 repositories, 214 orgs, 784 pushes a day, 245,417 commits, each contributor's count), a day's count scaled by a made-up factor, and a star count that began at 1,420. The forge's database holds 1,150 repositories and 46 orgs; none of that was read. Its panels were tinted rgba over a stylesheet, DualStarButton showed its guess before GitHub answered, and BulkStarModal said "successfully starred" over a forge PUT. scripts/sync-oss.ts (was .mjs) now counts GitHub's public activity for the orgs we publish: commits a day, the year, the week, active repositories and the newest commits, written at each build with the moment it was read. A figure the snapshot does not hold is not drawn. The grid, bars and repository card are @hanzo/ui/marketing (8.29.19); the showcase stylesheet and DayActivityModal are deleted. The org and repo pages lose their typed "velocity" banners. Design lint is zero in components/oss, home/OpenSource and ForgeBetaBanner. e2e/gates/activity.spec.ts holds each figure to the snapshot, the cards to one fill and edge in both schemes, a card's name, line and foot to their own rows, and the phone to no sideways scroll. Claude-Session: https://claude.ai/code/session_017vrVus6PPBgP5YRzKV1iqW
107 lines
5.3 KiB
TypeScript
107 lines
5.3 KiB
TypeScript
'use client'
|
|
|
|
import { useI18n } from '@hanzo/i18n/react'
|
|
import { Text, View, XStack, YStack } from '@hanzo/ui'
|
|
import { Heatmap, More, Sparkline } from '@hanzo/ui/marketing'
|
|
import activity from '@/lib/data/oss-activity.json'
|
|
import stats from '@/lib/data/oss-stats.json'
|
|
import { Card, Caption, Mono } from '@/components/home/plate'
|
|
import { Onward } from '@/components/home/label'
|
|
import { figures, weekly, type Figure as Counted } from '@/lib/activity'
|
|
|
|
/**
|
|
* What the public repositories shipped, counted and not typed.
|
|
*
|
|
* Every figure and every cell is read by scripts/sync-oss.ts off GitHub's public
|
|
* API for the repositories we publish (forks left out, because a fork's history
|
|
* is the upstream's), and written to lib/data/oss-activity.json and
|
|
* oss-stats.json at each build, and `stats.read` is the moment it was read. A figure that file does not hold is not drawn,
|
|
* and with no activity at all the section is not drawn: there is no placeholder
|
|
* number and no fallback. The grid and the bars are @hanzo/ui's (`Heatmap`,
|
|
* `Sparkline`): this file hands them the data and the words.
|
|
*/
|
|
|
|
const daily = activity.daily as Record<string, number>
|
|
const active = activity.active as Record<string, number>
|
|
|
|
const fmt = (n: number) => n.toLocaleString('en-US')
|
|
const label = (k: string) => new Date(`${k}T00:00:00Z`).toLocaleDateString('en-US', { timeZone: 'UTC', month: 'short', day: 'numeric', year: 'numeric' })
|
|
const hour = (iso: string) => new Date(iso).toLocaleString('en-US', { timeZone: 'UTC', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit', hour12: false })
|
|
|
|
function Figure({ id, title, value, caption, children }: { id: string; title: string; value: string; caption?: string; children?: React.ReactNode }) {
|
|
return (
|
|
<Card title={title}>
|
|
<Text fontFamily="$mono" fontSize="2rem" lineHeight="2.25rem" fontWeight="600" color="var(--foreground)" $platform-web={{ fontVariantNumeric: 'tabular-nums' }} data-figure={id}>
|
|
{value}
|
|
</Text>
|
|
{children}
|
|
{caption ? <Caption>{caption}</Caption> : null}
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
function Latest() {
|
|
const { t } = useI18n()
|
|
const rows = activity.latest as { repo: string; at: string; sha: string; message: string }[]
|
|
if (!rows.length) return null
|
|
return (
|
|
<Card title={t('Latest commits')}>
|
|
<YStack render="ul" $platform-web={{ listStyle: 'none', margin: 0, padding: 0 }} data-slot="latest">
|
|
{rows.map((r) => (
|
|
<XStack key={`${r.repo}@${r.sha}`} render="li" items="baseline" gap={16} py={10} borderTopWidth={1} borderColor="var(--border)" flexWrap="wrap" $md={{ flexWrap: 'nowrap' }}>
|
|
<Mono color="var(--muted-foreground)" shrink={0} width={200} $platform-web={{ whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
|
{r.repo}
|
|
</Mono>
|
|
<Text render={<a href={`https://github.com/${r.repo}/commit/${r.sha}`} target="_blank" rel="noopener noreferrer" />} flex={1} minW={200} fontSize="$2" lineHeight="$2" color="var(--foreground)" $platform-web={{ textDecoration: 'none' }}>
|
|
{r.message}
|
|
</Text>
|
|
<Mono color="var(--muted-foreground)" shrink={0} data-i18n-ltr>
|
|
<time dateTime={r.at}>{hour(r.at)} UTC</time>
|
|
</Mono>
|
|
</XStack>
|
|
))}
|
|
</YStack>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
/** The panel: the counted figures the snapshot holds, the year as a grid, and the newest commits. Not drawn without activity. */
|
|
export default function Activity() {
|
|
const { t } = useI18n()
|
|
if (!Object.keys(daily).length) return null
|
|
const titles = { year: t('Commits, past year'), week: t('Commits, past 7 days'), repos: t('Public repositories'), active: t('Active this month') } as const
|
|
const notes = (f: Counted) => (f.id === 'repos' && f.of != null ? t('{n} organizations', { n: f.of }) : f.id === 'active' ? t('repositories with a commit in 30 days') : undefined)
|
|
const shown = figures(stats)
|
|
return (
|
|
<YStack gap={16} data-slot="activity">
|
|
{shown.length ? (
|
|
<View display="grid" gridTemplateColumns="repeat(2, minmax(0, 1fr))" gap={12} $md={{ gridTemplateColumns: `repeat(${shown.length}, minmax(0, 1fr))`, gap: 16 }}>
|
|
{shown.map((f) => (
|
|
<Figure key={f.id} id={f.id} title={titles[f.id]} value={fmt(f.value)} caption={notes(f)}>
|
|
{f.id === 'year' ? <Sparkline values={weekly(daily, activity.from, activity.to)} label={t('Commits a week over the past year')} height={28} /> : null}
|
|
</Figure>
|
|
))}
|
|
</View>
|
|
) : null}
|
|
<Card title={t('Commits a day')}>
|
|
<Heatmap
|
|
days={daily}
|
|
from={activity.from}
|
|
to={activity.to}
|
|
locale="en-US"
|
|
label={t('Commits a day over the past year across our public repositories: {n} in all.', { n: fmt(stats.commits.year) })}
|
|
line={(day, n) => t('{date} ยท {n} commits across {repos} repositories', { date: label(day), n: fmt(n), repos: fmt(active[day] ?? 0) })}
|
|
rest={t('Commits a day, from {from} to {to}', { from: label(activity.from), to: label(activity.to) })}
|
|
legend={{ less: t('Less'), more: t('More') }}
|
|
/>
|
|
</Card>
|
|
<Latest />
|
|
<XStack justify="flex-end">
|
|
<More href="https://github.com/hanzoai">
|
|
<Onward>{t('Read the source')}</Onward>
|
|
</More>
|
|
</XStack>
|
|
</YStack>
|
|
)
|
|
}
|