166 lines · 5.7 KB
import { Link, useRouter } from "@tanstack/react-router";
import { useState } from "react";
import { deleteRelease, deleteReleaseAsset, updateRelease } from "~/fns/releases";
import { useAction } from "~/hooks/use-action";
import { Badge, formatBytes, Markdown, Panel, RelativeTime } from "./ui/Primitives";
import { Button } from "./ui/Button";
import { ErrorBanner } from "./ui/Field";
import type { listReleases } from "~/fns/releases";

type Release = Awaited<ReturnType<typeof listReleases>>["releases"][number];

function AssetUpload({ owner, repo, releaseId }: { owner: string; repo: string; releaseId: string }) {
  const router = useRouter();
  const [state, setState] = useState<{ status: "idle" | "uploading" } | { status: "error"; message: string }>({
    status: "idle",
  });
  return (
    <label className="inline-flex cursor-pointer items-center gap-2 text-xs text-accent-400 hover:underline">
      {state.status === "uploading" ? "Uploading…" : "Upload asset"}
      <input
        type="file"
        className="sr-only"
        onChange={async (event) => {
          const file = event.target.files?.[0];
          if (!file) return;
          setState({ status: "uploading" });
          const response = await fetch(
            `/${owner}/${repo}/releases/${releaseId}/assets?name=${encodeURIComponent(file.name)}`,
            {
              method: "POST",
              headers: { "x-gitfor-csrf": "1", "content-type": file.type || "application/octet-stream" },
              body: file,
            },
          );
          if (!response.ok) setState({ status: "error", message: await response.text() });
          else {
            setState({ status: "idle" });
            await router.invalidate();
          }
        }}