Download source/src/pages.jsx from mindchain/hub-flow: direct link, hf CLI and curl.
- Browser
- Download file 10.5 kB
-
https://huggingface.co/spaces/mindchain/hub-flow/resolve/main/source/src/pages.jsx
- Command line
-
hf download hf://spaces/mindchain/hub-flow/source/src/pages.jsx
-
curl -L -o pages.jsx https://huggingface.co/spaces/mindchain/hub-flow/resolve/main/source/src/pages.jsx
10.5 kB
| import React, { useEffect, useMemo, useState } from 'react' | |
| import { api, hubTop } from './api.js' | |
| import { BigChart, Stat, fmt, pct } from './components.jsx' | |
| export function Loading({ label }) { | |
| return ( | |
| <div className="state py-16 text-center text-sm text-[var(--dim)]"> | |
| <span className="mb-3 inline-block h-5 w-5 animate-spin rounded-full border-2 border-[var(--line)] border-t-[var(--dim)]" style={{ display: 'inline-block' }} /> | |
| <br />{label || 'Loading…'} | |
| </div> | |
| ) | |
| } | |
| export function ErrBox({ e, retry }) { | |
| return ( | |
| <div className="mt-10 rounded-xl border border-[var(--danger)]/40 bg-[var(--danger)]/5 p-8 text-center"> | |
| <p className="text-sm text-[var(--ink)]">Could not load data{e ? ' (' + e.message + ')' : ''}. The model-pulse API may be rate-limiting or down.</p> | |
| {retry && <button onClick={retry} className="mt-3 rounded-lg border border-[var(--line)] px-4 py-2 text-sm font-semibold hover:border-[var(--accent)]">Retry</button>} | |
| </div> | |
| ) | |
| } | |
| const REL_ORDER = ['quantized', 'finetune', 'adapter', 'merge'] | |
| const REL_LABEL = { quantized: 'Quantizations', finetune: 'Fine-tunes', adapter: 'Adapters', merge: 'Merges' } | |
| export function ModelPage({ id, go }) { | |
| const [data, setData] = useState(null) | |
| const [err, setErr] = useState(null) | |
| const load = () => { setErr(null); setData(null); api.model(id).then(setData).catch(setErr) } | |
| useEffect(load, [id]) | |
| if (err) return <ErrBox e={err} retry={load} /> | |
| if (!data) return <Loading label={'Loading ' + id + '…'} /> | |
| const m = data.model || {} | |
| const rel = data.series && data.series.day && data.series.day.length > 1 | |
| const groups = {} | |
| ;(data.children || []).forEach((c) => { (groups[c.relation] = groups[c.relation] || []).push(c) }) | |
| return ( | |
| <div className="rise"> | |
| <div className="flex flex-wrap items-center gap-2 pt-8"> | |
| <h1 className="break-all font-mono text-xl font-bold tracking-tight sm:text-2xl">{id}</h1> | |
| {m.pipeline_tag && <span className="rounded-full border border-[var(--line)] px-2.5 py-0.5 text-[11px] text-[var(--dim)]">{m.pipeline_tag}</span>} | |
| {m.is_gguf && <span className="rounded-full bg-[var(--accent)] px-2.5 py-0.5 text-[11px] font-bold text-black">GGUF</span>} | |
| {m.license && <span className="hidden rounded-full border border-[var(--line)] px-2.5 py-0.5 text-[11px] text-[var(--faint)] sm:inline">{String(m.license).slice(0, 40)}</span>} | |
| </div> | |
| <div className="mt-2 flex flex-wrap gap-x-4 gap-y-1 font-mono text-[11.5px] text-[var(--faint)]"> | |
| {m.params > 0 && <span>{(m.params / 1e9).toFixed(1)}B params</span>} | |
| {m.created_at && <span>created {String(m.created_at).slice(0, 10)}</span>} | |
| {m.first_seen && <span>tracked since {m.first_seen}</span>} | |
| {m.rank_dl30 != null && <span className="text-[var(--dim)]">rank dl30 <b className="text-[var(--ink)]">#{fmt(m.rank_dl30)}</b></span>} | |
| {m.rank_7d != null && <span className="text-[var(--dim)]">rank 7d <b className="text-[var(--ink)]">#{fmt(m.rank_7d)}</b></span>} | |
| <a className="underline decoration-[var(--line)] underline-offset-2 hover:decoration-[var(--dim)]" href={'https://huggingface.co/' + id} target="_blank" rel="noopener">open on the Hub ↗</a> | |
| </div> | |
| <div className="mt-6 grid grid-cols-2 divide-[var(--line)] overflow-hidden rounded-2xl border border-[var(--line)] bg-[var(--panel)] sm:grid-cols-3 lg:grid-cols-6 lg:divide-x"> | |
| <Stat k="Downloads 30d" v={m.dl30} sub={m.dl_7d != null ? fmt(m.dl_7d) + ' in 7d' : ''} /> | |
| <Stat k="All time" v={m.dl_all} /> | |
| <Stat k="7d vs prev" v={m.dl_7d} d={m.growth_7d != null ? pct(m.growth_7d) + ' vs week before' : ''} dCls={m.growth_7d >= 0 ? 'text-[var(--up)]' : 'text-[var(--danger)]'} /> | |
| <Stat k="Likes" v={m.likes} sub={m.likes_7d ? '+' + fmt(m.likes_7d) + ' in 7d' : ''} /> | |
| {m.fam_members != null && <Stat k="Family" v={m.fam_members} sub={fmt(m.fam_dl30) + ' dl30'} />} | |
| {m.trending != null && <Stat k="Trending score" v={m.trending} />} | |
| </div> | |
| <section className="mt-8 rounded-2xl border border-[var(--line)] bg-[var(--panel)] p-4 sm:p-6"> | |
| <div className="flex gap-5 text-[11.5px] text-[var(--dim)]"> | |
| <span><i className="mr-1.5 inline-block h-2 w-2 rounded-[2px] bg-[var(--bar)]" />downloads / day</span> | |
| <span><i className="mr-1.5 inline-block h-2 w-2 rounded-[2px] bg-[var(--accent)]" />cumulative</span> | |
| </div> | |
| {rel ? <BigChart series={data.series} /> : <p className="py-8 text-center text-sm text-[var(--dim)]">No history yet — too new.</p>} | |
| </section> | |
| {(data.children || []).length > 0 && ( | |
| <section className="mt-8"> | |
| <h2 className="border-b border-[var(--ink)] pb-2 text-[13px] font-bold uppercase tracking-[0.08em]"> | |
| Family <span className="font-medium normal-case tracking-normal text-[var(--faint)]">· {(data.children || []).length} derivatives (quantizations, fine-tunes, …)</span> | |
| </h2> | |
| {REL_ORDER.filter((r) => groups[r]).concat(Object.keys(groups).filter((r) => !REL_ORDER.includes(r))).map((rel2) => { | |
| const list = groups[rel2].slice().sort((a, b) => b.dl30 - a.dl30).slice(0, 8) | |
| const maxdl = Math.max(1, ...groups[rel2].map((c) => c.dl30)) | |
| return ( | |
| <div key={rel2} className="mt-5"> | |
| <h3 className="text-[12px] font-semibold uppercase tracking-[0.06em] text-[var(--dim)]">{REL_LABEL[rel2] || rel2} <span className="text-[var(--faint)]">· {groups[rel2].length}</span></h3> | |
| <table className="mt-1 w-full"> | |
| <tbody> | |
| {list.map((c) => ( | |
| <tr key={c.id} onClick={() => go('#/m/' + c.id)} className="cursor-pointer border-b border-[var(--line2)] transition-colors hover:bg-[var(--accent-soft)]/40"> | |
| <td className="break-all py-2.5 pl-1 pr-3 font-mono text-[12.5px]">{c.id}</td> | |
| <td className="w-[130px] px-3 py-2.5"><div className="h-1.5 rounded-full bg-[var(--line2)]"><div className="h-1.5 rounded-full bg-[var(--accent)]" style={{ width: Math.max(3, (c.dl30 / maxdl) * 100) + '%' }} /></div></td> | |
| <td className="tnum px-3 py-2.5 text-right text-[12.5px]">{fmt(c.dl30)}</td> | |
| <td className="tnum hidden px-3 py-2.5 text-right text-[var(--dim)] sm:table-cell">{fmt(c.dl_all)}</td> | |
| </tr> | |
| ))} | |
| </tbody> | |
| </table> | |
| {groups[rel2].length > 8 && <p className="mt-1 text-[11px] text-[var(--faint)]">+ {groups[rel2].length - 8} more</p>} | |
| </div> | |
| ) | |
| })} | |
| </section> | |
| )} | |
| </div> | |
| ) | |
| } | |
| export function AuthorPage({ author, go }) { | |
| const [data, setData] = useState(null) | |
| const [live, setLive] = useState(null) | |
| const [err, setErr] = useState(null) | |
| const load = () => { setErr(null); setData(null); api.author(author).then(setData).catch(setErr); hubTop('downloads', 1000).then((a) => setLive(a.filter((m) => m.id.startsWith(author + '/')))).catch(() => {}) } | |
| useEffect(load, [author]) | |
| if (err) return <ErrBox e={err} retry={load} /> | |
| if (!data) return <Loading label={'Loading ' + author + '…'} /> | |
| const models = (data.models || []).slice().sort((a, b) => (b.dl30 || 0) - (a.dl30 || 0)) | |
| const totals = data.totals || {} | |
| return ( | |
| <div className="rise"> | |
| <h1 className="break-all pt-8 text-2xl font-extrabold tracking-tight sm:text-3xl">{author}</h1> | |
| <div className="mt-6 grid grid-cols-2 divide-[var(--line)] overflow-hidden rounded-2xl border border-[var(--line)] bg-[var(--panel)] sm:grid-cols-4 lg:divide-x"> | |
| <Stat k="Models" v={(data.models || []).length} /> | |
| <Stat k="Downloads 30d" v={totals.dl30 != null ? totals.dl30 : models.reduce((a, m) => a + (m.dl30 || 0), 0)} /> | |
| <Stat k="All time" v={totals.dl_all != null ? totals.dl_all : models.reduce((a, m) => a + (m.dl_all || 0), 0)} /> | |
| <Stat k="Likes" v={totals.likes != null ? totals.likes : models.reduce((a, m) => a + (m.likes || 0), 0)} /> | |
| </div> | |
| <section className="mt-8 rounded-2xl border border-[var(--line)] bg-[var(--panel)] p-4 sm:p-6"> | |
| <h2 className="text-[12px] font-semibold uppercase tracking-[0.06em] text-[var(--dim)]">Author downloads, all models combined</h2> | |
| {data.series && data.series.day && data.series.day.length > 1 ? <BigChart series={data.series} /> : <p className="py-8 text-center text-sm text-[var(--dim)]">No history yet.</p>} | |
| </section> | |
| <section className="mt-8"> | |
| <h2 className="border-b border-[var(--ink)] pb-2 text-[13px] font-bold uppercase tracking-[0.08em]">Models <span className="font-medium normal-case tracking-normal text-[var(--faint)]">· {models.length}</span></h2> | |
| <table className="mt-1 w-full"> | |
| <thead> | |
| <tr className="text-[10.5px] uppercase tracking-[0.06em] text-[var(--faint)]"> | |
| <th className="py-2 pl-1 text-left font-semibold">Model</th> | |
| <th className="px-3 py-2 text-right font-semibold">30d</th> | |
| <th className="hidden px-3 py-2 text-right font-semibold sm:table-cell">All time</th> | |
| <th className="px-3 py-2 pr-1 text-right font-semibold">♥</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {models.map((m) => ( | |
| <tr key={m.id} onClick={() => go('#/m/' + m.id)} className="cursor-pointer border-b border-[var(--line2)] transition-colors hover:bg-[var(--accent-soft)]/40"> | |
| <td className="break-all py-2.5 pl-1 pr-3 font-mono text-[12.5px] font-semibold">{m.id.replace(author + '/', '')}{m.pipeline_tag && <span className="ml-2 hidden font-sans text-[11px] font-normal text-[var(--faint)] md:inline">{m.pipeline_tag}</span>}</td> | |
| <td className="tnum px-3 py-2.5 text-right font-semibold">{fmt(m.dl30)}</td> | |
| <td className="tnum hidden px-3 py-2.5 text-right sm:table-cell">{fmt(m.dl_all)}</td> | |
| <td className="tnum px-3 py-2.5 pr-1 text-right text-[var(--dim)]">♥ {fmt(m.likes)}</td> | |
| </tr> | |
| ))} | |
| </tbody> | |
| </table> | |
| {live && <p className="mt-2 text-[11px] text-[var(--faint)]">Cross-checked live with the Hub API ({live.length} public repos).</p>} | |
| </section> | |
| </div> | |
| ) | |
| } | |