defmodule AccrueAdmin.Components.Timeline do @moduledoc """ Shared vertical timeline for billing events and webhook attempt history. """ use Phoenix.Component attr(:items, :list, required: true) attr(:label, :string, default: "Timeline") attr(:empty_label, :string, default: "No events yet") attr(:class, :string, default: nil) def timeline(assigns) do ~H"""
  1. tone(item)]} aria-hidden="true">

    <%= Map.get(item, :title, "Event") %>

    <%= Map.get(item, :at) %>

    <%= humanize(Map.get(item, :status)) %>

    <%= Map.get(item, :body) %>

    Inspect details
    <%= Map.get(item, :details) %>
    <%= Map.get(item, :meta) %>

<%= @empty_label %>

""" end defp tone(item) do case Map.get(item, :tone) || Map.get(item, :status) do value when value in ["moss", "cobalt", "amber", "slate", "ink"] -> value value when value in [:moss, :cobalt, :amber, :slate, :ink] -> Atom.to_string(value) value when value in [:success, :succeeded, :paid, :active] -> "moss" value when value in [:info, :processing, :queued, :retrying] -> "cobalt" value when value in [:warning, :past_due, :failed_retry, :grace_period, :dlq] -> "amber" value when value in [:neutral, :void, :canceled] -> "slate" _ -> "ink" end end defp humanize(value) when is_atom(value), do: value |> Atom.to_string() |> humanize() defp humanize(value) when is_binary(value) do value |> String.replace("_", " ") |> String.split() |> Enum.map_join(" ", &String.capitalize/1) end defp humanize(_value), do: "Unknown" end