chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { ChevronDownIcon, ChevronRightIcon } from 'lucide-react';
import { useState } from 'react';
import { Badge } from '#/components/atoms/badge.jsx';
import { CopyCommand } from '#/components/molecules/copy-command.jsx';
import { bytes, timeAgo } from '#/lib/format.js';
/** One release line: its name, what it weighs, and when it was published. */
function ReleaseRow({ release }) {
return (
<div className="flex items-baseline gap-3 px-4 py-1.5 text-[12.5px]">
<span className="min-w-0 shrink-0 font-mono text-muted-foreground">
{release.name}
</span>
{release.digest && (
<span className="min-w-0 flex-1 truncate font-mono text-[11.5px] text-faint">
{release.digest}
</span>
)}
<span className="ml-auto shrink-0 text-[11.5px] text-faint">
{release.size > 0 && bytes(release.size)}
{release.publishedAt ? ` · ${timeAgo(release.publishedAt)}` : ''}
</span>
</div>
);
}
/**
* One package: what installs it, and every release behind a disclosure. An
* npm package lists its versions, an image its tags.
*/
export function PackageCard({ pkg }) {
const [open, setOpen] = useState(false);
const Chevron = open ? ChevronDownIcon : ChevronRightIcon;
const count = pkg.releases.length;
const noun = pkg.registry === 'oci' ? 'tag' : 'version';
return (
<li className="border-border border-b">
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 px-4 pt-4 pb-2">
<span className="min-w-0 truncate font-semibold text-[13.5px]">
{pkg.name}
</span>
{pkg.latest && <Badge variant="scope">{pkg.latest}</Badge>}
<span className="text-[12px] text-faint">{pkg.label}</span>
<span className="ml-auto flex shrink-0 items-center gap-3 text-[12px] text-faint">
{pkg.size > 0 && <span>{bytes(pkg.size)}</span>}
{pkg.updatedAt && <span>published {timeAgo(pkg.updatedAt)}</span>}
</span>
</div>
<div className="px-4 pb-3">
<CopyCommand
command={pkg.install}
label={`Copy the command that installs ${pkg.name}`}
/>
</div>
{count > 0 && (
<>
<button
type="button"
onClick={() => setOpen(!open)}
className="flex w-full cursor-pointer items-center gap-1.5 px-4 pb-3 text-left text-[12.5px] text-muted-foreground hover:text-foreground"
>
<Chevron className="size-3.5 shrink-0" />
{count} {count === 1 ? noun : `${noun}s`}
</button>
{open && (
<div className="max-h-72 overflow-y-auto border-border border-t bg-muted py-1">
{pkg.releases.map((release) => (
<ReleaseRow key={release.name} release={release} />
))}
</div>
)}
</>
)}
</li>
);
}