foxygit / RPA-Remisser Log in
commits tags

/webui/frontend/src/components/ImageField.tsx · 1.97 KB

raw
import { useEffect, useState } from "react";
import { ApiError, api } from "../lib/api";

interface Props {
  label: string;
  value: string;
  onChange: (v: string) => void;
}

/** Fält för desktop_*_image-stegens referensbild: filnamn + "Fånga"-knapp +
 *  lista över befintliga bilder + miniatyr. */
export function ImageField({ label, value, onChange }: Props) {
  const [images, setImages] = useState<string[]>([]);
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState<string | null>(null);

  const refresh = () => api.listDesktopImages().then(setImages).catch(() => {});
  useEffect(() => {
    refresh();
  }, []);

  async function capture() {
    const suggested = value.replace(/\.png$/i, "") || `bild ${images.length + 1}`;
    const name = window.prompt("Namn på referensbilden:", suggested);
    if (name === null) return;
    setBusy(true);
    setErr(null);
    try {
      const res = await api.captureDesktopImage(name.trim());
      onChange(res.name);
      await refresh();
    } catch (e) {
      setErr(e instanceof ApiError ? String(e.detail) : String(e));
    } finally {
      setBusy(false);
    }
  }

  const known = value && images.includes(value);

  return (
    <label className="field image-field">
      <span>{label}</span>
      <div className="image-field-row">
        <input
          type="text"
          list="desktop-images"
          value={value ?? ""}
          placeholder="filnamn.png"
          onChange={(e) => onChange(e.target.value)}
        />
        <datalist id="desktop-images">
          {images.map((n) => (
            <option key={n} value={n} />
          ))}
        </datalist>
        <button type="button" className="secondary tiny" disabled={busy} onClick={capture}>
          {busy ? "…" : "📷 Fånga"}
        </button>
      </div>
      {known && <img className="image-field-preview" src={api.desktopImageUrl(value)} alt={value} />}
      {err && <span className="assist-msg error">{err}</span>}
    </label>
  );
}