forms-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev ce303909347f
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone cf614aedcf4cdabfa9c45095
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
src/YourForms.tsx
// "Your forms" on the landing page, for returning owners. Read from this browser only.
import { useEffect, useState } from "react";
import { listMine, forget, type Mine } from "./lib/mine";
import { usePath } from "./lib/router";
import { confirmAction } from "./ui";

export function YourForms() {
  const path = usePath();
  const [mine, setMine] = useState<Mine[]>(listMine);
  useEffect(() => setMine(listMine()), [path]);
  if (!mine.length) return null;
  const remove = async (m: Mine) => {
    if (!(await confirmAction({
      title: "Remove it from this list?",
      body: `"${m.title || "Untitled form"}" keeps working and keeps its responses. To manage it again in this browser, open its admin link.`,
      action: "Remove",
    }))) return;
    forget(m.id);
    setMine(listMine());
  };
  return (
    <section className="section-tight your-forms">
      <div className="wrap">
        <div className="spread">
          <h2 className="h2">Your forms</h2>
          <a className="btn btn-line" href="/new" data-nav>New form</a>
        </div>
        <p className="muted small" style={{ marginTop: 8 }}>Forms you made or opened with an admin link in this browser.</p>
        <ul className="mine-list">
          {mine.map((m, i) => (
            <li key={m.id} className="enter" style={{ ["--i" as string]: i }}>
              <a className="mine-title" href={`/f/${m.id}/results`} data-nav>{m.title || "Untitled form"}</a>
              <span className="row mine-actions">
                <a className="btn btn-sm btn-line" href={`/f/${m.id}/responses`} data-nav>Responses</a>
                <a className="btn btn-sm btn-quiet" href={`/f/${m.id}/edit`} data-nav>Edit</a>
                <button className="btn btn-sm btn-quiet" type="button" onClick={() => remove(m)} aria-label={`Remove ${m.title || "Untitled form"} from this list`}>Remove</button>
              </span>
            </li>
          ))}
        </ul>
      </div>
    </section>
  );
}

Change history

Quality pass: conditional questions, 0 to 10 scale, QR code, prefill links, results tabs, API docs
ce30390934 · 4 hours ago
Bounded source sync
7d82add8ae · 1 day ago
Bounded source sync
8230fd7d59 · 1 day ago
Bounded source sync
d92a6e3b44 · 1 day ago
Bounded source sync
b548641922 · 1 day ago
Bounded source sync
b89074ffd2 · 1 day ago