defmodule PhoenixKit.Modules.Sync.Web.Index do @moduledoc """ Landing page for DB Sync module. Provides access to: - Manage Connections: Create and manage permanent connections with other sites - Transfer History: View all data transfers with approval workflow """ use PhoenixKitWeb, :live_view use Gettext, backend: PhoenixKitWeb.Gettext alias PhoenixKit.Modules.Sync alias PhoenixKit.Modules.Sync.Connections alias PhoenixKit.Settings alias PhoenixKit.Utils.Routes @impl true def mount(params, _session, socket) do locale = params["locale"] || "en" project_title = Settings.get_project_title() config = Sync.get_config() # Get connection stats stats = get_connection_stats() socket = socket |> assign(:page_title, "DB Sync") |> assign(:project_title, project_title) |> assign(:current_locale, locale) |> assign(:current_path, Routes.path("/admin/sync", locale: locale)) |> assign(:config, config) |> assign(:stats, stats) {:ok, socket} end @impl true def handle_params(_params, _url, socket) do {:noreply, socket} end defp get_connection_stats do default_stats = %{ total_senders: 0, total_receivers: 0, active_senders: 0, active_receivers: 0 } with {:ok, sender_connections} <- safe_list_connections("sender"), {:ok, receiver_connections} <- safe_list_connections("receiver") do active_senders = Enum.count(sender_connections, &(&1.status == "active")) active_receivers = Enum.count(receiver_connections, &(&1.status == "active")) %{ total_senders: length(sender_connections), total_receivers: length(receiver_connections), active_senders: active_senders, active_receivers: active_receivers } else _ -> default_stats end end defp safe_list_connections(direction) do {:ok, Connections.list_connections(direction: direction)} rescue _ -> {:error, :unavailable} end @impl true def render(assigns) do ~H"""
<%!-- Header Section --%>
<.link navigate={Routes.path("/admin")} class="btn btn-outline btn-primary btn-sm absolute left-0 top-0 -mb-12" > <.icon name="hero-arrow-left" class="w-4 h-4 mr-2" /> Back to Dashboard

DB Sync

Sync data between PhoenixKit instances with permanent connections

<%= if not @config.enabled do %>
<.icon name="hero-exclamation-triangle" class="w-5 h-5" /> DB Sync module is disabled. Enable it in <.link navigate={Routes.path("/admin/modules")} class="link link-primary"> Modules to use this feature.
<% end %> <%!-- Stats Overview (commented out for now - will add back later) <%= if @config.enabled do %>
<.icon name="hero-arrow-up-tray" class="w-8 h-8" />
Sender Connections
{@stats.total_senders}
{@stats.active_senders} active
<.icon name="hero-arrow-down-tray" class="w-8 h-8" />
Receiver Connections
{@stats.total_receivers}
{@stats.active_receivers} active
<.icon name="hero-check-circle" class="w-8 h-8" />
Total Active
{@stats.active_senders + @stats.active_receivers}
connections ready
<% end %> --%> <%!-- Main Actions --%>
<%!-- Manage Connections Card --%>
<.icon name="hero-link" class="w-16 h-16 text-primary" />

Manage Connections

Create sender connections to share your data with other sites. Receiver connections are created automatically when remote sites connect.

<.link navigate={Routes.path("/admin/sync/connections", locale: @current_locale)} class="btn btn-primary btn-lg" > <.icon name="hero-cog-6-tooth" class="w-5 h-5" /> Manage Connections
<%!-- Transfer History Card --%>
<.icon name="hero-clock" class="w-16 h-16 text-secondary" />

Transfer History

View all data transfers and monitor sync activity. Track records transferred and connection statistics.

<.link navigate={Routes.path("/admin/sync/history", locale: @current_locale)} class="btn btn-secondary btn-lg" > <.icon name="hero-queue-list" class="w-5 h-5" /> View History
<%!-- How It Works Section --%>

<.icon name="hero-information-circle" class="w-5 h-5" /> How Cross-Site Connections Work

<.icon name="hero-arrow-up-tray" class="w-5 h-5" /> As a Sender

  1. Create a sender connection with a name
  2. Enter the remote site's URL
  3. The remote site is notified automatically
  4. They can now pull data from your tables

<.icon name="hero-arrow-down-tray" class="w-5 h-5" /> As a Receiver

  1. When another site creates a connection to you
  2. A receiver connection appears automatically
  3. Use it to sync data from their site
  4. Choose conflict strategy when importing
Security: All connections use token-based authentication.
""" end end