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

chadtmiller.com/pds.js

An atproto PDS in JavaScript, for Cloudflare Workers and Node

0
0
main
78 lines · 2.8 KB Raw History
import { useQuery } from '@tanstack/react-query';
import { Notice } from '#/components/atoms/notice.jsx';
import { Panel } from '#/components/atoms/panel.jsx';
import { Skeleton } from '#/components/atoms/skeleton.jsx';
import { Section } from '#/components/molecules/section.jsx';
import { BackupKeyCard } from '#/components/organisms/backup-key-card.jsx';
import { BackupRunsCard } from '#/components/organisms/backup-runs-card.jsx';
import { BackupSettingsCard } from '#/components/organisms/backup-settings-card.jsx';
import { RepoDownloadCard } from '#/components/organisms/repo-download-card.jsx';
import { get } from '#/lib/api.js';
import { queryKeys } from '#/lib/query.js';

export function BackupsPage({ data }) {
  const { data: backups, error } = useQuery({
    queryKey: queryKeys.backups,
    queryFn: () => get('/backups'),
    // While a run is live its counters change server-side every few seconds;
    // poll so the history row ticks instead of sitting at zero.
    refetchInterval: (query) =>
      query.state.data?.runs?.some((run) => run.status === 'running')
        ? 3000
        : false,
  });

  if (error) {
    return <Notice variant="error">{error.message}</Notice>;
  }
  if (!backups) {
    return (
      <div className="grid grid-cols-1 items-start gap-5 lg:grid-cols-[1fr_360px]">
        <div className="space-y-5">
          <Skeleton className="h-64 rounded-3xl" />
          <Skeleton className="h-40 rounded-3xl" />
        </div>
        <div className="space-y-5">
          <Skeleton className="h-48 rounded-3xl" />
          <Skeleton className="h-32 rounded-3xl" />
        </div>
      </div>
    );
  }

  const download = <RepoDownloadCard did={data.did} handle={data.handle} />;

  if (!backups.available) {
    return (
      <div className="grid grid-cols-1 items-start gap-5 lg:grid-cols-[1fr_360px]">
        <Panel>
          <Section title="Automatic backups">
            <Notice>
              Automatic backups need a backup target configured on the server.
              On Node or Deno, set{' '}
              <span className="font-mono text-foreground">PDS_BACKUP_DIR</span>{' '}
              or S3 credentials in the environment; on Cloudflare, bind a{' '}
              <span className="font-mono text-foreground">BACKUPS</span> R2
              bucket. Until then, you can still download a copy of your
              repository here.
            </Notice>
          </Section>
        </Panel>
        <div className="space-y-5">{download}</div>
      </div>
    );
  }

  return (
    <div className="grid grid-cols-1 items-start gap-5 lg:grid-cols-[1fr_360px]">
      <div className="space-y-5">
        <BackupSettingsCard data={backups} />
        <BackupRunsCard data={backups} />
      </div>
      <div className="space-y-5">
        <BackupKeyCard data={backups} />
        {download}
      </div>
    </div>
  );
}