git » hoplite.git » master » tree

[master] / hntr2.mjs

import { input, formula, watch, cond, not, database, transaction } from './reactives.mjs';
import { h, nbsp, entities, bindTo } from './el.mjs';
import { record } from './record.mjs';

let user = input(),
    loaded = input(false),
    db = database([
      // [0, "site", "foo.com"]
    ]);

firebase.auth().onAuthStateChanged(result => {
  if (result) user.set(result)
  loaded.set(true);
});

function authed() {
  let rec = record("site", "username", "password", "note"),
      regex = input("\\w{10}");
  return h.div(
    h.p(
      formula(u => `Signed in as ${u?.email}`)(user),
      nbsp,
      h.a({href: "#", onclick: () => {
        firebase.auth().signOut().then(() => user.set());
      }}, "Sign out")
    ),
    h.div(
      h.table(
        h.tr(
          h.th("Site"),
          h.th("Username"),
          h.th("Password"),
          h.th("Note")
        ),
        h.tr(
          ...rec.fields.map(name => {
            return h.td(bindTo(h.input({
              type: "text",
              id: `input-${name}`
            }), rec.get(name)))
          })
        ),
        h.tr(
          h.td(
            {colspan: 4},
            h.button({onclick: () => rec.clear()}, "clr"),
            h.button({onclick: () => {
              db.add(rec.asTriples(db.nextEid()));
              rec.clear();
            }}, "add"),
            h.input({type: "button", value: "genpw", onclick: () => {
              rec.get("password").set(new RandExp(regex.value).gen());
            }}),
            bindTo(h.input({type: "text", value: regex}), regex)
          )
        ),
        entities(db, "_eid", "asc", attrs => {
          
          return h.tr(
            // h.td(h.input({
            //   type: "button",
            //   value: "Delete",
            //   onclick: () => db.deleteEntity(attrs._eid.value)
            // })),
            h.td(attrs.site),
            h.td(attrs.username),
            h.td(attrs.password),
            h.td(attrs.note)
          )
        })
      )
    ),
    (() => {
      let prdb = input();
      watch(() => prdb.set(js_beautify(JSON.stringify([...db]))))(db);
      return h.pre(prdb);
    })()
  );
}

function login() {
  let provider = new firebase.auth.GoogleAuthProvider(),
      errorCode = input(),
      errorMessage = input();
  return h.div(
    cond(
      errorCode,
      formula((code, message) => {
        return `Error ${code}: ${message}`
      })(errorCode, errorMessage)
    ),
    h.a({
      href: "#",
      onclick: () => firebase.auth()
        .setPersistence(firebase.auth.Auth.Persistence.SESSION)
        .then(() => firebase.auth().signInWithPopup(provider))
        .then(result => user.set(result.user))
        .catch((error) => transaction(() => {
          errorCode.set(error.code);
          errorMessage.set(error.message);
        }))
    }, "Sign in")
  );
}

function app() {
  return h.div(
    h.h1("hntr2"),
    cond(
      not(loaded),
      "Loading...",
      true,
      cond(
        user,
        authed(),
        true,
        login()
      )
    )
  );
}

document.addEventListener("DOMContentLoaded", () => {
  document.body.appendChild(app());
});