puerto 0.14.0

Puerto — Rust full-stack DDD framework CLI. Scaffolds Clean Architecture projects with auto-wired DI, SQLx support, and zero manual wiring. Formerly puerto-framework.
{% if enums %}import { {% for e in enums %}parse{{ e.name }}, {% endfor %}type {{ pascal }}, type {{ pascal }}Draft }{% else %}import type { {{ pascal }}, {{ pascal }}Draft }{% endif %} from "../../../../domain/{{ kebab }}/model";
{%- if form_helpers %}
import { {{ form_helpers | join(sep=", ") }} } from "../../../shared/forms";
{%- endif %}

/** What the inputs hold: the text of every input, `checked` for a checkbox. */
export interface {{ pascal }}FormValues {
{%- for f in fields %}
  {{ f.camel }}: {% if f.input == "checkbox" %}boolean{% else %}string{% endif %};
{%- endfor %}
}

/** The inputs for `{{ ident }}`, empty when there is none yet. */
export function to{{ pascal }}Form({{ ident }}: {{ pascal }} | null): {{ pascal }}FormValues {
  if ({{ ident }} === null) {
    return {
{%- for f in fields %}
      {{ f.camel }}: {{ f.empty_form }},
{%- endfor %}
    };
  }
  return {
{%- for f in fields %}
    {{ f.camel }}: {{ f.to_form }},
{%- endfor %}
  };
}

export function to{{ pascal }}Draft(values: {{ pascal }}FormValues): {{ pascal }}Draft {
  return {
{%- for f in fields %}
    {{ f.camel }}: {{ f.from_form }},
{%- endfor %}
  };
}

export function {{ pascal }}FormView({
  values,
  saving,
  onChange,
  onSubmit,
}: {
  values: {{ pascal }}FormValues;
  saving: boolean;
  onChange: (values: {{ pascal }}FormValues) => void;
  onSubmit: () => void;
}) {
  return (
    <form
      className="space-y-2"
      onSubmit={(event) => {
        event.preventDefault();
        onSubmit();
      }}
    >
{%- for f in fields %}
{%- if f.input == "checkbox" %}
      <label className="label">
        <input
          className="checkbox"
          type="checkbox"
          checked={values.{{ f.camel }}}
          onChange={(event) => onChange({ ...values, {{ f.camel }}: event.target.checked })}
        />
        {{ f.label }}
      </label>
{%- elif f.input == "select" %}
      <label className="fieldset">
        <span className="fieldset-legend">{{ f.label }}</span>
        <select
          className="select w-full"
{%- if f.required %}
          required
{%- endif %}
          value={values.{{ f.camel }}}
          onChange={(event) => onChange({ ...values, {{ f.camel }}: event.target.value })}
        >
          <option value="">{{ f.placeholder }}</option>
{%- for o in f.options %}
          <option value="{{ o.value }}">{{ o.label }}</option>
{%- endfor %}
        </select>
      </label>
{%- elif f.input == "textarea" %}
      <label className="fieldset">
        <span className="fieldset-legend">{{ f.label }}</span>
        <textarea
          className="textarea w-full"
          placeholder="key=value, one per line"
          value={values.{{ f.camel }}}
          onChange={(event) => onChange({ ...values, {{ f.camel }}: event.target.value })}
        />
      </label>
{%- else %}
      <label className="fieldset">
        <span className="fieldset-legend">{{ f.label }}</span>
        <input
          className="input w-full"
          type="{{ f.input }}"
{%- if f.decimal %}
          step="any"
{%- endif %}
{%- if f.required %}
          required
{%- endif %}
          value={values.{{ f.camel }}}
          onChange={(event) => onChange({ ...values, {{ f.camel }}: event.target.value })}
        />
      </label>
{%- endif %}
{%- endfor %}
      <button type="submit" className="btn btn-primary" disabled={saving}>
        Save
      </button>
    </form>
  );
}