Packages
phoenix_kit
1.7.185
1.7.210
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
Current section
Files
lib/phoenix_kit_web/live/modules/notifications/index.ex
defmodule PhoenixKitWeb.Live.Modules.Notifications.Index do
@moduledoc """
Admin overview for the Notifications module — enabled state, retention
window, aggregate counts (total / unread / dismissed), and a paginated
list of every notification showing its recipient, what it's about, and
its per-user seen/dismissed state.
Read-only. Enabling/disabling the module lives on the Modules page;
this page redirects there if the module is disabled.
"""
use PhoenixKitWeb, :live_view
alias PhoenixKit.Notifications
alias PhoenixKit.Notifications.Render
alias PhoenixKit.Settings
alias PhoenixKit.Utils.Date, as: UtilsDate
alias PhoenixKit.Utils.Routes
@per_page 25
@impl true
def mount(_params, _session, socket) do
if Notifications.enabled?() do
socket =
socket
|> assign(:page_title, "Notifications")
|> assign(:project_title, Settings.get_project_title())
|> assign(:url_path, Routes.path("/admin/notifications"))
|> assign(:retention_days, Notifications.retention_days())
|> assign(:stats, Notifications.admin_stats())
|> assign(:per_page, @per_page)
|> assign(:page, 1)
{:ok, socket}
else
{:ok,
socket
|> put_flash(
:error,
"Notifications module is not enabled. Enable it from the Modules page."
)
|> redirect(to: Routes.path("/admin/modules"))}
end
end
@impl true
def handle_params(params, url, socket) do
# Skip when mount redirected (module disabled) — assigns won't be set up.
if socket.assigns[:per_page] do
{:noreply,
socket
|> assign(:page, parse_page(params["page"]))
|> assign(:url_path, URI.parse(url).path)
|> load_notifications()}
else
{:noreply, socket}
end
end
@impl true
def handle_event("refresh", _params, socket) do
{:noreply,
socket
|> assign(:stats, Notifications.admin_stats())
|> load_notifications()}
end
## Private
defp load_notifications(socket) do
{rows, total} =
Notifications.admin_list(page: socket.assigns.page, per_page: socket.assigns.per_page)
# Deep-link each recipient to their admin page, via the shared resolver.
recipient_links =
rows
|> Enum.map(&%{resource_type: "user", resource_uuid: &1.recipient_uuid})
|> PhoenixKit.ResourceLinks.resolve()
socket
|> assign(:notifications, rows)
|> assign(:total, total)
|> assign(:total_pages, max(ceil(total / socket.assigns.per_page), 1))
|> assign(:recipient_links, recipient_links)
end
defp parse_page(nil), do: 1
defp parse_page(str) when is_binary(str) do
case Integer.parse(str) do
{n, _} -> max(n, 1)
:error -> 1
end
end
# Rendered notification (icon + text) for display, honoring the admin's locale.
defp render_notification(notification, locale), do: Render.render(notification, locale)
# Per-user lifecycle state → a badge label + daisyUI class.
defp status_meta(%{dismissed_at: %DateTime{}}), do: {"Dismissed", "badge-ghost"}
defp status_meta(%{seen_at: %DateTime{}}), do: {"Seen", "badge-neutral"}
defp status_meta(_), do: {"Unread", "badge-primary"}
defp format_datetime(%DateTime{} = dt) do
"#{UtilsDate.format_date_with_user_format(dt)} #{UtilsDate.format_time_with_user_format(dt)}"
end
defp format_datetime(_), do: ""
end