{# Admin panel: usuarios. Contract con el backend host: - GET users_list_url → JSON {users: [{id, email, role, created_at}], page, total_pages} - POST invite_url → body {email, role} - PATCH user_role_url → body {role} (URL templated: replace {id}) - POST password_reset_url (URL templated) - DELETE user_delete_url (URL templated) Por simplicidad, esta plantilla renderiza una vista server-side: la host app le pasa ``users``, ``page``, ``total_pages``, ``next_url``, ``prev_url``. #} {% from "dg/components/page_header.html" import page_header %} {% from "dg/components/button.html" import button %} {% from "dg/components/paginated_table.html" import paginated_table %} {% from "dg/components/modal.html" import modal_open %} {% from "dg/components/form_field.html" import field %} {% call page_header(title="Usuarios", subtitle="Gestión de cuentas y roles") %} {{ button("Invitar usuario", variant="primary", attrs="onclick=\"openModal('dg-invite-user')\"") }} {% endcall %} {{ paginated_table( columns=["Email", "Rol", "Creado", ""], keys=["email", "role", "created_at_label", "_actions_html"], rows=users, page=page | default(1), total_pages=total_pages | default(1), prev_url=prev_url, next_url=next_url, target="#dg-users-table", empty_message="No hay usuarios todavía." ) }} {% call modal_open(id="dg-invite-user", title="Invitar usuario") %}
{{ field("email", label="Email", type="email", required=true, autocomplete="email") }} {{ field("role", label="Rol", type="select", required=true, options=[ {"value": "viewer", "label": "Viewer"}, {"value": "editor", "label": "Editor"}, {"value": "admin", "label": "Admin"}, ]) }}
{{ button("Cancelar", variant="ghost", attrs="onclick=\"closeModal('dg-invite-user')\"") }} {{ button("Enviar invitación", variant="primary", type="submit") }}
{% endcall %}