defmodule PhoenixKit.Modules.Shared.Components.EntityForm do @moduledoc """ Embeddable entity form component for publishing pages. Renders a public submission form based on entity configuration. ## Usage in .phk files ## Attributes - `entity_slug` (required) - The slug/name of the entity to render form for """ use Phoenix.Component use Gettext, backend: PhoenixKitWeb.Gettext alias PhoenixKit.Modules.Entities alias PhoenixKit.Modules.Entities.EntityData alias PhoenixKit.Modules.Entities.FormBuilder alias PhoenixKit.Utils.Date, as: UtilsDate attr :content, :string, default: nil attr :attributes, :map, default: %{} attr :variant, :string, default: "default" def render(assigns) do entity_slug = Map.get(assigns.attributes, "entity_slug", "") # Load entity and check if public form is enabled entity = if entity_slug != "", do: Entities.get_entity_by_name(entity_slug), else: nil {form_enabled, form_fields, form_title, form_description, form_submit_text, honeypot_enabled} = if entity do settings = entity.settings || %{} enabled = Map.get(settings, "public_form_enabled", false) fields = Map.get(settings, "public_form_fields", []) # Form is only truly enabled if it's enabled AND has at least one field selected actually_enabled = enabled && not Enum.empty?(fields) title = Map.get(settings, "public_form_title", "") description = Map.get(settings, "public_form_description", "") submit_text = Map.get(settings, "public_form_submit_text", gettext("Submit")) honeypot = Map.get(settings, "public_form_honeypot", false) {actually_enabled, fields, title, description, submit_text, honeypot} else {false, [], "", "", gettext("Submit"), false} end # Create a form entity with only the public form fields form_entity = if entity && form_enabled do fields_definition = entity.fields_definition || [] public_fields = Enum.filter(fields_definition, fn field -> field["key"] in form_fields end) %{entity | fields_definition: public_fields} else nil end assigns = assigns |> assign(:entity_slug, entity_slug) |> assign(:entity, entity) |> assign(:form_entity, form_entity) |> assign(:form_enabled, form_enabled) |> assign(:form_title, form_title) |> assign(:form_description, form_description) |> assign(:form_submit_text, form_submit_text) |> assign(:honeypot_enabled, honeypot_enabled) |> assign(:form_timestamp, UtilsDate.utc_now() |> DateTime.to_iso8601()) ~H"""
<%= cond do %> <% @entity_slug == "" -> %>
⚠️

{gettext("Form configuration error.")}

<% is_nil(@entity) -> %>
⚠️

{gettext("Form configuration error.")}

<% !@form_enabled -> %>
📝

{gettext("This form is currently unavailable.")}

<% true -> %>
<%= if @form_title != "" do %>

{@form_title}

<% end %> <%= if @form_description != "" do %>

{@form_description}

<% end %>
<%!-- Form loaded timestamp (always included for metadata) --%> <%!-- Honeypot field (hidden from humans, bots will fill it) --%> <%= if @honeypot_enabled do %> <% end %> {FormBuilder.build_fields(@form_entity, build_empty_changeset(@entity), wrapper_class: "mb-4" )}
<% end %>
""" end defp build_empty_changeset(entity) do # Create an empty EntityData changeset for the form %EntityData{entity_uuid: entity.uuid, data: %{}} |> EntityData.change() end end