defmodule Bloccs.Web.Router do
@moduledoc """
Router helpers for mounting the bloccs dashboard into a host Phoenix app.
Add one macro call inside a `scope` and pipe it through whatever auth your
app already uses:
defmodule MyAppWeb.Router do
use MyAppWeb, :router
import Bloccs.Web.Router
scope "/" do
pipe_through [:browser, :require_admin]
bloccs_dashboard "/bloccs"
end
end
The dashboard inherits the host's auth from the pipeline; per-feature
authorization (the Pro seam) is delegated to a `Bloccs.Web.Resolver`.
"""
@doc """
Mount the bloccs dashboard at `path`.
## Options
* `:resolver` — a module implementing `Bloccs.Web.Resolver`, consulted for
the current user, access level, and enabled features. Defaults to
`Bloccs.Web.Access` (everything visible — the free baseline).
* `:as` — the route helper name. Defaults to `:bloccs_dashboard`.
* `:on_mount` — extra `on_mount` hooks appended to the dashboard's own.
All four panels live under a single `live_session` so navigating between them
never triggers a full remount.
"""
defmacro bloccs_dashboard(path, opts \\ []) do
quote bind_quoted: binding() do
resolver = Keyword.get(opts, :resolver, Bloccs.Web.Access)
as = Keyword.get(opts, :as, :bloccs_dashboard)
extra_on_mount = List.wrap(Keyword.get(opts, :on_mount, []))
session_args = %{"resolver" => to_string(resolver), "base_path" => path}
# The dashboard's own precompiled bundles, served from priv/static so the
# host needs no Plug.Static config. Inherits the surrounding pipeline.
forward "#{path}/assets", Bloccs.Web.Assets
live_session :bloccs_dashboard,
session: session_args,
root_layout: {Bloccs.Web.Layouts, :root},
on_mount: [{Bloccs.Web.DashboardLive, {:resolver, resolver}} | extra_on_mount] do
# One LiveView, four actions (oban_web style) — no remount on nav.
live "#{path}", Bloccs.Web.DashboardLive, :networks, as: as
live "#{path}/networks", Bloccs.Web.DashboardLive, :networks, as: as
live "#{path}/networks/:network", Bloccs.Web.DashboardLive, :topology, as: as
live "#{path}/networks/:network/messages", Bloccs.Web.DashboardLive, :messages, as: as
live "#{path}/networks/:network/metrics", Bloccs.Web.DashboardLive, :metrics, as: as
live "#{path}/networks/:network/coverage", Bloccs.Web.DashboardLive, :coverage, as: as
end
end
end
end