~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
79 lines · 2.8 KB Raw History
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>
  );
}