lib/pgflow_dashboard/components/data_table.ex

defmodule PgFlowDashboard.Components.DataTable do
  @moduledoc """
  Sortable, filterable data table component.
  """

  use Phoenix.Component

  @doc """
  Renders a data table.

  ## Attributes

    * `:rows` - List of row data (maps)
    * `:columns` - List of column definitions

  ## Column Definition

  Each column is a map with:
    * `:key` - The key to extract from each row
    * `:label` - Display label
    * `:class` - Optional CSS class for the column

  """
  attr(:rows, :list, required: true)
  attr(:columns, :list, required: true)
  attr(:row_click, :any, default: nil)
  attr(:empty_message, :string, default: "No data available")

  def data_table(assigns) do
    ~H"""
    <div class="overflow-x-auto">
      <table class="min-w-full divide-y divide-slate-200 dark:divide-slate-700">
        <thead class="bg-slate-50 dark:bg-slate-800/50">
          <tr>
            <%= for col <- @columns do %>
              <th
                scope="col"
                class={[
                  "px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider",
                  col[:class]
                ]}
              >
                {col.label}
              </th>
            <% end %>
          </tr>
        </thead>
        <tbody class="bg-white dark:bg-slate-800 divide-y divide-slate-200 dark:divide-slate-700">
          <%= if @rows == [] do %>
            <tr>
              <td colspan={length(@columns)} class="px-4 py-8 text-center text-slate-500 dark:text-slate-400">
                {@empty_message}
              </td>
            </tr>
          <% else %>
            <%= for row <- @rows do %>
              <tr class={[
                "hover:bg-slate-50 dark:hover:bg-slate-700/50 transition-colors",
                @row_click && "cursor-pointer"
              ]}>
                <%= for col <- @columns do %>
                  <td class={[
                    "px-4 py-3 text-sm text-slate-700 dark:text-slate-300",
                    col[:class]
                  ]}>
                    {render_cell(Map.get(row, col.key), col)}
                  </td>
                <% end %>
              </tr>
            <% end %>
          <% end %>
        </tbody>
      </table>
    </div>
    """
  end

  defp render_cell(value, %{render: render_fn}) when is_function(render_fn, 1) do
    render_fn.(value)
  end

  defp render_cell(nil, _col), do: "-"
  defp render_cell(value, _col), do: to_string(value)
end