# `PhoenixKit.Dashboard.Presence`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.87/lib/phoenix_kit/dashboard/presence.ex#L1)

Presence tracking for dashboard tabs.

Tracks which users are viewing which dashboard tabs, enabling features like:
- "2 users viewing" indicators on tabs
- Real-time user count updates
- Activity heatmaps
- User awareness for collaborative features

## Integration with PhoenixKit Presence

This module integrates with PhoenixKit's existing presence system to provide
dashboard-specific tracking while sharing the underlying infrastructure.

## Usage in LiveViews

    def mount(_params, _session, socket) do
      if connected?(socket) do
        # Track user on this tab
        PhoenixKit.Dashboard.Presence.track_tab(socket, :orders)

        # Subscribe to presence updates
        PhoenixKit.Dashboard.Presence.subscribe()
      end

      {:ok, assign(socket, tab_viewers: Presence.get_tab_viewers(:orders))}
    end

    def handle_info({:presence_diff, _diff}, socket) do
      {:noreply, assign(socket, tab_viewers: Presence.get_tab_viewers(:orders))}
    end

## Configuration

    config :phoenix_kit, :dashboard_presence,
      enabled: true,
      show_user_count: true,
      show_user_names: false,  # Privacy setting
      track_anonymous: false

# `broadcast_tab_count`

```elixir
@spec broadcast_tab_count(atom()) :: :ok
```

Broadcasts a tab viewer count update.

This is called automatically when presence changes, but can also be
called manually to force a refresh.

# `clear_presence_module_cache`

```elixir
@spec clear_presence_module_cache() :: :ok
```

Clears the cached presence module detection.

Call this after hot code reloading if the presence module configuration
has changed. The next call to any presence function will re-detect.

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

Checks if presence tracking is enabled.

# `get_all_tab_counts`

```elixir
@spec get_all_tab_counts() :: map()
```

Gets viewer counts for all tabs at once.

Returns a map of tab_id => count.

## Examples

    Presence.get_all_tab_counts()
    # => %{orders: 3, printers: 1, settings: 0}

# `get_tab_viewers`

```elixir
@spec get_tab_viewers(
  atom(),
  keyword()
) :: list() | integer()
```

Gets all users currently viewing a specific tab.

## Options

- `:format` - Output format: :full (default), :count, :emails, :ids

## Examples

    Presence.get_tab_viewers(:orders)
    # => [%{user_uuid: "019...", user_email: "user@example.com", online_at: ~U[...]}]

    Presence.get_tab_viewers(:orders, format: :count)
    # => 3

    Presence.get_tab_viewers(:orders, format: :emails)
    # => ["user@example.com", "admin@example.com"]

# `presence_topic`

```elixir
@spec presence_topic() :: String.t()
```

Gets the main presence topic for all dashboard presence updates.

# `show_user_count?`

```elixir
@spec show_user_count?() :: boolean()
```

Checks if user counts should be shown.

# `show_user_names?`

```elixir
@spec show_user_names?() :: boolean()
```

Checks if user names/emails should be shown.

# `subscribe`

```elixir
@spec subscribe() :: :ok | {:error, term()}
```

Subscribes to presence updates for all dashboard tabs.

The subscriber will receive messages in the format:
- `{:presence_diff, %{joins: %{}, leaves: %{}}}` - When users join/leave
- `{:tab_viewers_updated, tab_id, count}` - Simplified count update

# `subscribe_tab`

```elixir
@spec subscribe_tab(atom()) :: :ok | {:error, term()}
```

Subscribes to presence updates for a specific tab.

# `tab_topic`

```elixir
@spec tab_topic(atom()) :: String.t()
```

Gets the presence topic for a specific tab.

# `track_anonymous?`

```elixir
@spec track_anonymous?() :: boolean()
```

Checks if anonymous users should be tracked.

# `track_tab`

```elixir
@spec track_tab(Phoenix.LiveView.Socket.t(), atom(), keyword()) ::
  {:ok, String.t()} | {:error, term()}
```

Tracks a user's presence on a specific dashboard tab.

## Options

- `:meta` - Additional metadata to track with the presence (default: %{})
- `:tab_path` - The full path of the tab (used for analytics)

## Examples

    Presence.track_tab(socket, :orders)
    Presence.track_tab(socket, :printers, meta: %{printer_id: 123})

# `untrack_tab`

```elixir
@spec untrack_tab(Phoenix.LiveView.Socket.t(), atom()) :: :ok
```

Untracks a user from a dashboard tab.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
