Packages

phoenix_kit

1.7.111
1.7.209 1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib phoenix_kit_web live dashboard.ex
Raw

lib/phoenix_kit_web/live/dashboard.ex

defmodule PhoenixKitWeb.Live.Dashboard do
@moduledoc """
Admin dashboard LiveView for PhoenixKit.
Provides real-time system statistics, user metrics, and session monitoring.
"""
use PhoenixKitWeb, :live_view
use Gettext, backend: PhoenixKitWeb.Gettext
alias PhoenixKit.Admin.{Events, Presence}
alias PhoenixKit.Migrations.Postgres, as: Migrations
alias PhoenixKit.Settings
alias PhoenixKit.Users.Auth.Scope
alias PhoenixKit.Users.{Roles, Sessions}
alias PhoenixKit.Utils.Date, as: UtilsDate
alias PhoenixKit.Utils.IpAddress
alias PhoenixKit.Utils.Routes
def mount(_params, session, socket) do
# Subscribe to statistics updates for live data
if connected?(socket) do
Events.subscribe_to_stats()
Events.subscribe_to_sessions()
Events.subscribe_to_presence()
# Track authenticated user session if logged in
track_authenticated_session(socket, session)
end
# Load extended statistics including activity and confirmation status (now optimized!)
stats = Roles.get_extended_stats()
session_stats = Sessions.get_session_stats()
presence_stats = Presence.get_presence_stats()
# Get PhoenixKit version from application specification
version = Application.spec(:phoenix_kit, :vsn) |> to_string()
# Get migration versions
migration_current = Migrations.current_version()
migration_db = Migrations.migrated_version_runtime(%{prefix: "public"})
# Get project title from settings cache
project_title = Settings.get_project_title()
# Cache user roles from scope to avoid repeated DB queries
user_roles =
case socket.assigns[:phoenix_kit_current_scope] do
%{cached_roles: cached_roles} when is_list(cached_roles) -> cached_roles
_ -> []
end
socket =
socket
|> assign(:stats, stats)
|> assign(:session_stats, session_stats)
|> assign(:presence_stats, presence_stats)
|> assign(:phoenix_kit_version, version)
|> assign(:migration_current, migration_current)
|> assign(:migration_db, migration_db)
|> assign(:project_title, project_title)
|> assign(:page_title, "Dashboard")
|> assign(:cached_user_roles, user_roles)
{:ok, socket}
end
def handle_event("refresh_stats", _params, socket) do
# Refresh statistics with optimized single query
stats = Roles.get_extended_stats()
session_stats = Sessions.get_session_stats()
presence_stats = Presence.get_presence_stats()
socket =
socket
|> assign(:stats, stats)
|> assign(:session_stats, session_stats)
|> assign(:presence_stats, presence_stats)
|> assign(:stats_last_updated, :os.system_time(:second))
|> put_flash(:info, gettext("Statistics refreshed successfully"))
{:noreply, socket}
end
# Handle live statistics updates from PubSub
def handle_info({:stats_updated, stats}, socket) do
socket =
socket
|> assign(:stats, stats)
|> assign(:stats_last_updated, :os.system_time(:second))
{:noreply, socket}
end
# Handle live session statistics updates from PubSub
def handle_info({:sessions_stats_updated, session_stats}, socket) do
socket =
socket
|> assign(:session_stats, session_stats)
{:noreply, socket}
end
# Handle live presence statistics updates from PubSub
def handle_info({:presence_stats_updated, presence_stats}, socket) do
socket =
socket
|> assign(:presence_stats, presence_stats)
{:noreply, socket}
end
def handle_info({:anonymous_session_connected, _session_id, _metadata}, socket) do
{:noreply, update_presence_stats(socket)}
end
def handle_info({:anonymous_session_disconnected, _session_id}, socket) do
{:noreply, update_presence_stats(socket)}
end
def handle_info({:user_session_connected, _user_uuid, _metadata}, socket) do
{:noreply, update_presence_stats(socket)}
end
def handle_info({:user_session_disconnected, _user_uuid, _session_id}, socket) do
{:noreply, update_presence_stats(socket)}
end
defp update_presence_stats(socket) do
assign(socket, :presence_stats, Presence.get_presence_stats())
end
defp track_authenticated_session(socket, session) do
scope = socket.assigns[:phoenix_kit_current_scope]
if scope && Scope.authenticated?(scope) do
user_uuid = Scope.user_uuid(scope)
user_email = Scope.user_email(scope)
# Create a user map for tracking (uuid required by SimplePresence)
user = %{uuid: user_uuid, email: user_email}
session_id = session["live_socket_id"] || generate_session_id()
Presence.track_user(user, %{
connected_at: UtilsDate.utc_now(),
session_id: session_id,
ip_address: IpAddress.extract_from_socket(socket),
user_agent: get_connect_info(socket, :user_agent),
current_page: Routes.path("/admin")
})
end
end
defp generate_session_id do
:crypto.strong_rand_bytes(16) |> Base.encode64()
end
end