towerops/lib/towerops_web/live/agent_live/helpers.ex
Graham McIntire ae16acf016
Add build timestamp to footer with shared time formatting helpers
- Add compile-time @build_timestamp to Application module
- Create ToweropsWeb.TimeHelpers module for shared time formatting
- Update footer to display 'Last deployed Xm ago · YYYY-MM-DD HH:MM:SS UTC'
- Refactor AgentLive.Helpers to delegate to shared TimeHelpers
- Consolidate duplicate time formatting logic into single module
- Timestamp updates automatically on each build/deploy
2026-01-17 11:10:50 -06:00

114 lines
3.3 KiB
Elixir

defmodule ToweropsWeb.AgentLive.Helpers do
@moduledoc """
Shared helper functions for agent LiveView modules.
"""
@doc """
Determines the agent's status based on last_seen_at timestamp.
Returns a tuple of {status_atom, status_label} where status_atom is:
- :online - Last seen within 2 minutes
- :warning - Last seen between 2-5 minutes
- :offline - Last seen more than 5 minutes ago
- :never - Never connected
"""
def agent_status(agent_token) do
case agent_token.last_seen_at do
nil ->
{:never, "Never connected"}
last_seen ->
seconds_ago = DateTime.diff(DateTime.utc_now(), last_seen, :second)
cond do
seconds_ago < 120 -> {:online, "Online"}
seconds_ago < 300 -> {:warning, "Warning"}
true -> {:offline, "Offline"}
end
end
end
@doc """
Returns Tailwind CSS classes for status badge background and text colors.
"""
def status_badge_class(status) do
case status do
:online -> "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300"
:warning -> "bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300"
:offline -> "bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300"
:never -> "bg-zinc-100 text-zinc-800 dark:bg-zinc-800 dark:text-zinc-300"
end
end
@doc """
Returns Tailwind CSS classes for status indicator dot.
Online status includes animation.
"""
def status_dot_class(status) do
case status do
:online -> "bg-green-600 dark:bg-green-400 animate-pulse"
:warning -> "bg-yellow-600 dark:bg-yellow-400"
:offline -> "bg-red-600 dark:bg-red-400"
:never -> "bg-zinc-400 dark:bg-zinc-600"
end
end
@doc """
Formats a DateTime into a human-readable "time ago" string.
Returns strings like "5s ago", "3m ago", "2h ago", or "5d ago".
Delegates to ToweropsWeb.TimeHelpers.format_time_ago/1.
"""
defdelegate format_last_seen(datetime), to: ToweropsWeb.TimeHelpers, as: :format_time_ago
@doc """
Formats uptime in seconds to a human-readable string.
Returns strings like "2h 34m" or "5d 3h".
"""
def format_uptime(uptime_seconds) when is_integer(uptime_seconds) do
days = div(uptime_seconds, 86_400)
hours = div(rem(uptime_seconds, 86_400), 3600)
minutes = div(rem(uptime_seconds, 3600), 60)
cond do
days > 0 -> "#{days}d #{hours}h"
hours > 0 -> "#{hours}h #{minutes}m"
true -> "#{minutes}m"
end
end
def format_uptime(_), do: "Unknown"
@doc """
Formats a DateTime into a full date and time string.
Returns strings like "Jan 15, 2026 at 2:34 PM UTC".
Delegates to ToweropsWeb.TimeHelpers.format_datetime/1.
"""
defdelegate format_datetime(datetime), to: ToweropsWeb.TimeHelpers
@doc """
Formats a DateTime into a short date string.
Returns strings like "Jan 15, 2026".
Delegates to ToweropsWeb.TimeHelpers.format_date/1.
"""
defdelegate format_date(datetime), to: ToweropsWeb.TimeHelpers
@doc """
Formats a DateTime into a relative time with full datetime in parentheses.
Returns strings like "5m ago (Jan 15, 2026 at 2:34 PM UTC)".
"""
def format_last_seen_with_date(nil), do: "Never"
def format_last_seen_with_date(datetime) do
relative = format_last_seen(datetime)
full = format_datetime(datetime)
"#{relative} (#{full})"
end
end