foxygit / RPA-Remisser Log in
commits tags

/webui/frontend/src/components/SettingsDialog.tsx · 2.25 KB

raw
import { useEffect, useRef, type FormEvent } from "react";
import type { Schema } from "../lib/schema";
import { fieldLabel } from "../lib/schema";
import type { Lang, T } from "../lib/i18n";

interface Props {
  open: boolean;
  schema: Schema;
  lang: Lang;
  t: T;
  settings: Record<string, unknown>;
  onClose: () => void;
  onSave: (settings: Record<string, unknown>) => void;
}

export function SettingsDialog({ open, schema, lang, t, settings, onClose, onSave }: Props) {
  const ref = useRef<HTMLDialogElement>(null);
  useEffect(() => {
    const d = ref.current;
    if (!d) return;
    if (open && !d.open) d.showModal();
    if (!open && d.open) d.close();
  }, [open]);

  function save(e: FormEvent) {
    e.preventDefault();
    const form = e.currentTarget as HTMLFormElement;
    const next: Record<string, unknown> = {};
    for (const s of schema.settings) {
      const el = form.elements.namedItem(s.key) as HTMLInputElement | null;
      if (!el) continue;
      if (s.kind === "bool") next[s.key] = el.checked;
      else if (s.kind === "number") next[s.key] = Number(el.value) || Number(s.default) || 0;
      else next[s.key] = el.value || String(s.default);
    }
    onSave(next);
  }

  return (
    <dialog ref={ref} onClose={onClose}>
      <form onSubmit={save} method="dialog">
        <h2>{t("settings")}</h2>
        <p className="hint">{t("settings_hint")}</p>
        <div className="fields">
          {schema.settings.map((s) => (
            <label className={"field" + (s.kind === "bool" ? " field-bool" : "")} key={s.key}>
              <span>{fieldLabel(s, lang)}</span>
              {s.kind === "bool" ? (
                <input type="checkbox" name={s.key} defaultChecked={settings[s.key] === true} />
              ) : (
                <input
                  type={s.kind === "number" ? "number" : "text"}
                  name={s.key}
                  defaultValue={String(settings[s.key] ?? s.default)}
                />
              )}
            </label>
          ))}
        </div>
        <div className="dialog-actions">
          <button type="button" className="secondary" onClick={onClose}>
            {t("cancel")}
          </button>
          <button type="submit">{t("save")}</button>
        </div>
      </form>
    </dialog>
  );
}