114 lines
3.3 KiB
Elixir
114 lines
3.3 KiB
Elixir
defmodule ToweropsWeb.UserSettingsLive.Helpers do
|
|
@moduledoc """
|
|
Helper functions for formatting and displaying user settings data.
|
|
"""
|
|
|
|
@doc """
|
|
Checks if a session matches the current token ID.
|
|
"""
|
|
def current_session?(session, current_token_id) do
|
|
session.user_token_id == current_token_id
|
|
end
|
|
|
|
@doc """
|
|
Formats a UTC datetime in the user's timezone.
|
|
"""
|
|
def format_timestamp_in_timezone(datetime, timezone) do
|
|
case DateTime.shift_zone(datetime, timezone) do
|
|
{:ok, shifted} ->
|
|
Calendar.strftime(shifted, "%b %d, %Y %I:%M %p %Z")
|
|
|
|
{:error, _} ->
|
|
# Fallback to UTC if timezone conversion fails
|
|
Calendar.strftime(datetime, "%b %d, %Y %I:%M %p UTC")
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats browser information from a session for display.
|
|
"""
|
|
def format_browser_info(session) do
|
|
case {session.browser_name, session.browser_version, session.os_name} do
|
|
{nil, _, _} -> session.device_name || "Unknown Browser"
|
|
{browser, nil, nil} -> browser
|
|
{browser, version, nil} -> "#{browser} #{version}"
|
|
{browser, nil, os} -> "#{browser} on #{os}"
|
|
{browser, version, os} -> "#{browser} #{version} on #{os}"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats location information from GeoIP data.
|
|
"""
|
|
def format_location(record) do
|
|
case {record.city_name, record.subdivision_1_name, record.country_name} do
|
|
{nil, nil, nil} ->
|
|
"Unknown Location"
|
|
|
|
{city, state, country} when not is_nil(city) and not is_nil(state) and not is_nil(country) ->
|
|
"#{city}, #{state}, #{country}"
|
|
|
|
{city, nil, country} when not is_nil(city) and not is_nil(country) ->
|
|
"#{city}, #{country}"
|
|
|
|
{nil, nil, country} when not is_nil(country) ->
|
|
country
|
|
|
|
_ ->
|
|
"Unknown Location"
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Formats a datetime as a relative time string (e.g., "5 minutes ago").
|
|
"""
|
|
def format_relative_time(datetime) do
|
|
now = DateTime.utc_now()
|
|
diff = DateTime.diff(now, datetime, :second)
|
|
|
|
cond do
|
|
diff < 60 -> "Just now"
|
|
diff < 3600 -> "#{div(diff, 60)} minutes ago"
|
|
diff < 86_400 -> "#{div(diff, 3600)} hours ago"
|
|
diff < 604_800 -> "#{div(diff, 86_400)} days ago"
|
|
true -> Calendar.strftime(datetime, "%b %d, %Y")
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Returns icon name and display label for a login method.
|
|
"""
|
|
def login_method_info(method) do
|
|
case method do
|
|
"password" -> {"hero-lock-closed", "Password"}
|
|
"magic_link" -> {"hero-envelope", "Magic Link"}
|
|
"mobile_qr" -> {"hero-device-phone-mobile", "Mobile QR"}
|
|
_ -> {"hero-question-mark-circle", method}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Generates pagination range with ellipsis for large page counts.
|
|
|
|
Shows: [1] ... [4] [5] [6] ... [20] when on page 5 of 20
|
|
"""
|
|
def pagination_range(current_page, total_pages) do
|
|
cond do
|
|
total_pages <= 7 ->
|
|
# Show all pages if 7 or fewer
|
|
Enum.to_list(1..total_pages)
|
|
|
|
current_page <= 4 ->
|
|
# Near the start
|
|
[1, 2, 3, 4, 5, :ellipsis, total_pages]
|
|
|
|
current_page >= total_pages - 3 ->
|
|
# Near the end
|
|
[1, :ellipsis, total_pages - 4, total_pages - 3, total_pages - 2, total_pages - 1, total_pages]
|
|
|
|
true ->
|
|
# In the middle
|
|
[1, :ellipsis, current_page - 1, current_page, current_page + 1, :ellipsis, total_pages]
|
|
end
|
|
end
|
|
end
|