Packages

phoenix_kit

1.7.9
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 modules.ex
Raw

lib/phoenix_kit_web/live/modules.ex

defmodule PhoenixKitWeb.Live.Modules do
@moduledoc """
Admin modules management LiveView for PhoenixKit.
Displays available system modules and their configuration status.
"""
use PhoenixKitWeb, :live_view
use Gettext, backend: PhoenixKitWeb.Gettext
alias PhoenixKit.AI
alias PhoenixKit.Billing
alias PhoenixKit.DBSync
alias PhoenixKit.Entities
alias PhoenixKit.Modules.Languages
alias PhoenixKit.Modules.Maintenance
alias PhoenixKit.Modules.SEO
alias PhoenixKit.Modules.Storage
alias PhoenixKit.Pages
alias PhoenixKit.Posts
alias PhoenixKit.ReferralCodes
alias PhoenixKit.Settings
alias PhoenixKit.Sitemap
alias PhoenixKit.Tickets
alias PhoenixKit.Utils.Date, as: UtilsDate
alias PhoenixKitWeb.Live.Modules.Blogging
def mount(_params, _session, socket) do
# Set locale for LiveView process
# Get project title from settings
project_title = Settings.get_setting("project_title", "PhoenixKit")
# Load module states
referral_codes_config = ReferralCodes.get_config()
email_config = PhoenixKit.Emails.get_config()
languages_config = Languages.get_config()
entities_config = Entities.get_config()
pages_enabled = Pages.enabled?()
blogging_enabled = Blogging.enabled?()
under_construction_config = Maintenance.get_config()
seo_config = SEO.get_config()
storage_config = Storage.get_config()
sitemap_config = Sitemap.get_config()
billing_config = Billing.get_config()
posts_config = Posts.get_config()
ai_config = AI.get_config()
db_sync_config = DBSync.get_config()
tickets_config = Tickets.get_config()
socket =
socket
|> assign(:page_title, "Modules")
|> assign(:project_title, project_title)
|> assign(:referral_codes_enabled, referral_codes_config.enabled)
|> assign(:referral_codes_required, referral_codes_config.required)
|> assign(:max_uses_per_code, referral_codes_config.max_uses_per_code)
|> assign(:max_codes_per_user, referral_codes_config.max_codes_per_user)
|> assign(:email_enabled, email_config.enabled)
|> assign(:email_save_body, email_config.save_body)
|> assign(:email_ses_events, email_config.ses_events)
|> assign(:email_retention_days, email_config.retention_days)
|> assign(:languages_enabled, languages_config.enabled)
|> assign(:languages_count, languages_config.language_count)
|> assign(:languages_enabled_count, languages_config.enabled_count)
|> assign(:languages_default, languages_config.default_language)
|> assign(:entities_enabled, entities_config.enabled)
|> assign(:entities_count, entities_config.entity_count)
|> assign(:entities_total_data, entities_config.total_data_count)
|> assign(:pages_enabled, pages_enabled)
|> assign(:blogging_enabled, blogging_enabled)
|> assign(:under_construction_module_enabled, under_construction_config.module_enabled)
|> assign(:under_construction_enabled, under_construction_config.enabled)
|> assign(:under_construction_header, under_construction_config.header)
|> assign(:under_construction_subtext, under_construction_config.subtext)
|> assign(:storage_enabled, storage_config.module_enabled)
|> assign(:storage_buckets_count, storage_config.buckets_count)
|> assign(:storage_active_buckets_count, storage_config.active_buckets_count)
|> assign(:seo_module_enabled, seo_config.module_enabled)
|> assign(:seo_no_index_enabled, seo_config.no_index_enabled)
|> assign(:sitemap_enabled, sitemap_config.enabled)
|> assign(:sitemap_url_count, sitemap_config.url_count)
|> assign(:sitemap_last_generated, sitemap_config.last_generated)
|> assign(:sitemap_schedule_enabled, sitemap_config.schedule_enabled)
|> assign(:billing_enabled, billing_config.enabled)
|> assign(:billing_orders_count, billing_config.orders_count)
|> assign(:billing_invoices_count, billing_config.invoices_count)
|> assign(:billing_currencies_count, billing_config.currencies_count)
|> assign(:ai_enabled, ai_config.enabled)
|> assign(:ai_endpoints_count, ai_config.endpoints_count)
|> assign(:ai_total_requests, ai_config.total_requests)
|> assign(:posts_enabled, posts_config.enabled)
|> assign(:posts_total, posts_config.total_posts)
|> assign(:posts_published, posts_config.published_posts)
|> assign(:posts_draft, posts_config.draft_posts)
|> assign(:db_sync_enabled, db_sync_config.enabled)
|> assign(:db_sync_active_sessions, db_sync_config.active_sessions)
|> assign(:tickets_enabled, tickets_config.enabled)
|> assign(:tickets_total, tickets_config.total_tickets)
|> assign(:tickets_open, tickets_config.open_tickets)
|> assign(:tickets_in_progress, tickets_config.in_progress_tickets)
{:ok, socket}
end
def handle_event("toggle_referral_codes", _params, socket) do
# Since we're sending "toggle", we just flip the current state
new_enabled = !socket.assigns.referral_codes_enabled
result =
if new_enabled do
ReferralCodes.enable_system()
else
ReferralCodes.disable_system()
end
case result do
{:ok, _setting} ->
socket =
socket
|> assign(:referral_codes_enabled, new_enabled)
|> put_flash(
:info,
if(new_enabled,
do: "Referral codes enabled",
else: "Referral codes disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update referral codes")
{:noreply, socket}
end
end
def handle_event("toggle_emails", _params, socket) do
# Toggle email system
new_enabled = !socket.assigns.email_enabled
result =
if new_enabled do
PhoenixKit.Emails.enable_system()
else
PhoenixKit.Emails.disable_system()
end
case result do
{:ok, _setting} ->
socket =
socket
|> assign(:email_enabled, new_enabled)
|> put_flash(
:info,
if(new_enabled,
do: "Email system enabled",
else: "Email system disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update email system")
{:noreply, socket}
end
end
def handle_event("toggle_languages", _params, socket) do
# Toggle languages
new_enabled = !socket.assigns.languages_enabled
result =
if new_enabled do
Languages.enable_system()
else
Languages.disable_system()
end
case result do
{:ok, _} ->
# Reload languages configuration to get fresh data
languages_config = Languages.get_config()
socket =
socket
|> assign(:languages_enabled, new_enabled)
|> assign(:languages_count, languages_config.language_count)
|> assign(:languages_enabled_count, languages_config.enabled_count)
|> assign(:languages_default, languages_config.default_language)
|> put_flash(
:info,
if(new_enabled,
do: "Languages enabled with default English",
else: "Languages disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update languages")
{:noreply, socket}
end
end
def handle_event("toggle_entities", _params, socket) do
# Toggle entities system
new_enabled = !socket.assigns.entities_enabled
result =
if new_enabled do
Entities.enable_system()
else
Entities.disable_system()
end
case result do
{:ok, _} ->
# Reload entities configuration to get fresh data
entities_config = Entities.get_config()
socket =
socket
|> assign(:entities_enabled, new_enabled)
|> assign(:entities_count, entities_config.entity_count)
|> assign(:entities_total_data, entities_config.total_data_count)
|> put_flash(
:info,
if(new_enabled,
do: "Entities system enabled",
else: "Entities system disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update entities system")
{:noreply, socket}
end
end
def handle_event("toggle_seo_module", _params, socket) do
new_enabled = !socket.assigns.seo_module_enabled
result =
if new_enabled do
SEO.enable_module()
else
SEO.disable_module()
end
case result do
{:ok, _setting} ->
seo_no_index_enabled =
if new_enabled do
SEO.no_index_enabled?()
else
false
end
message =
if new_enabled do
"SEO module enabled - configure options in Settings → SEO"
else
"SEO module disabled and search directives reset"
end
socket =
socket
|> assign(:seo_module_enabled, new_enabled)
|> assign(:seo_no_index_enabled, seo_no_index_enabled)
|> put_flash(:info, message)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update SEO module")
{:noreply, socket}
end
end
def handle_event("toggle_blogging", _params, socket) do
new_enabled = !socket.assigns.blogging_enabled
result =
if new_enabled do
Blogging.enable_system()
else
Blogging.disable_system()
end
case result do
{:ok, _} ->
socket =
socket
|> assign(:blogging_enabled, new_enabled)
|> put_flash(
:info,
if(new_enabled,
do: "Blogging module enabled",
else: "Blogging module disabled"
)
)
{:noreply, socket}
{:error, _reason} ->
{:noreply, put_flash(socket, :error, "Failed to update blogging module")}
end
end
def handle_event("toggle_pages", _params, socket) do
# Toggle pages system
new_enabled = !socket.assigns.pages_enabled
result =
if new_enabled do
Pages.enable_system()
else
Pages.disable_system()
end
case result do
{:ok, _setting} ->
socket =
socket
|> assign(:pages_enabled, new_enabled)
|> put_flash(
:info,
if(new_enabled,
do: "Pages module enabled",
else: "Pages module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update pages module")
{:noreply, socket}
end
end
def handle_event("toggle_under_construction", _params, socket) do
# Toggle under construction module (settings page access)
new_module_enabled = !socket.assigns.under_construction_module_enabled
result =
if new_module_enabled do
Maintenance.enable_module()
else
Maintenance.disable_module()
end
case result do
{:ok, _setting} ->
socket =
socket
|> assign(:under_construction_module_enabled, new_module_enabled)
|> put_flash(
:info,
if(new_module_enabled,
do: "Maintenance mode module enabled - configure settings to activate",
else: "Maintenance mode module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update maintenance mode module")
{:noreply, socket}
end
end
def handle_event("toggle_sitemap", _params, socket) do
new_enabled = !socket.assigns.sitemap_enabled
result =
if new_enabled do
Sitemap.enable_system()
else
Sitemap.disable_system()
end
case result do
{:ok, _} ->
sitemap_config = Sitemap.get_config()
socket =
socket
|> assign(:sitemap_enabled, new_enabled)
|> assign(:sitemap_url_count, sitemap_config.url_count)
|> assign(:sitemap_last_generated, sitemap_config.last_generated)
|> assign(:sitemap_schedule_enabled, sitemap_config.schedule_enabled)
|> put_flash(
:info,
if(new_enabled,
do: "Sitemap module enabled",
else: "Sitemap module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update sitemap module")
{:noreply, socket}
end
end
def handle_event("toggle_billing", _params, socket) do
new_enabled = !socket.assigns.billing_enabled
result =
if new_enabled do
Billing.enable_system()
else
Billing.disable_system()
end
case result do
{:ok, _} ->
billing_config = Billing.get_config()
socket =
socket
|> assign(:billing_enabled, new_enabled)
|> assign(:billing_orders_count, billing_config.orders_count)
|> assign(:billing_invoices_count, billing_config.invoices_count)
|> assign(:billing_currencies_count, billing_config.currencies_count)
|> put_flash(
:info,
if(new_enabled,
do: "Billing module enabled",
else: "Billing module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update billing module")
{:noreply, socket}
end
end
def handle_event("toggle_ai", _params, socket) do
new_enabled = !socket.assigns.ai_enabled
result =
if new_enabled do
AI.enable_system()
else
AI.disable_system()
end
case result do
{:ok, _} ->
ai_config = AI.get_config()
socket =
socket
|> assign(:ai_enabled, new_enabled)
|> assign(:ai_endpoints_count, ai_config.endpoints_count)
|> assign(:ai_total_requests, ai_config.total_requests)
|> put_flash(
:info,
if(new_enabled,
do: "AI module enabled",
else: "AI module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update AI module")
{:noreply, socket}
end
end
def handle_event("toggle_posts", _params, socket) do
new_enabled = !socket.assigns.posts_enabled
result =
if new_enabled do
Posts.enable_system()
else
Posts.disable_system()
end
case result do
{:ok, _} ->
posts_config = Posts.get_config()
socket =
socket
|> assign(:posts_enabled, new_enabled)
|> assign(:posts_total, posts_config.total_posts)
|> assign(:posts_published, posts_config.published_posts)
|> assign(:posts_draft, posts_config.draft_posts)
|> put_flash(
:info,
if(new_enabled,
do: "Posts module enabled",
else: "Posts module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update posts module")
{:noreply, socket}
end
end
def handle_event("toggle_db_sync", _params, socket) do
new_enabled = !socket.assigns.db_sync_enabled
result =
if new_enabled do
DBSync.enable_system()
else
DBSync.disable_system()
end
case result do
{:ok, _} ->
db_sync_config = DBSync.get_config()
socket =
socket
|> assign(:db_sync_enabled, new_enabled)
|> assign(:db_sync_active_sessions, db_sync_config.active_sessions)
|> put_flash(
:info,
if(new_enabled,
do: "DB Sync module enabled",
else: "DB Sync module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update DB Sync module")
{:noreply, socket}
end
end
def handle_event("toggle_tickets", _params, socket) do
new_enabled = !socket.assigns.tickets_enabled
result =
if new_enabled do
Tickets.enable_system()
else
Tickets.disable_system()
end
case result do
{:ok, _} ->
tickets_config = Tickets.get_config()
socket =
socket
|> assign(:tickets_enabled, new_enabled)
|> assign(:tickets_total, tickets_config.total_tickets)
|> assign(:tickets_open, tickets_config.open_tickets)
|> assign(:tickets_in_progress, tickets_config.in_progress_tickets)
|> put_flash(
:info,
if(new_enabled,
do: "Tickets module enabled",
else: "Tickets module disabled"
)
)
{:noreply, socket}
{:error, _changeset} ->
socket = put_flash(socket, :error, "Failed to update tickets module")
{:noreply, socket}
end
end
# Format ISO8601 timestamp string to user-friendly format with system timezone
def format_timestamp(nil), do: "Never"
def format_timestamp(iso_string) when is_binary(iso_string) do
case DateTime.from_iso8601(iso_string) do
{:ok, dt, _} ->
# Use fake user with nil timezone to get system timezone from Settings
fake_user = %{user_timezone: nil}
date_str = UtilsDate.format_date_with_user_timezone(dt, fake_user)
time_str = UtilsDate.format_time_with_user_timezone(dt, fake_user)
"#{date_str} #{time_str}"
_ ->
iso_string
end
end
def format_timestamp(_), do: "Never"
end