mirror of
https://github.com/wanderer-industries/wanderer
synced 2026-05-02 23:40:29 +00:00
646 lines
26 KiB
Plaintext
646 lines
26 KiB
Plaintext
<div class="grid grid-flow-row gap-2 p-3 h-full w-full pl-20">
|
|
<main class="w-full rounded-lg shadow col-span-2 lg:col-span-1 overflow-auto p-3">
|
|
<div class="gap-4 grid grid-cols-2 lg:grid-cols-5 md:grid-cols-3 sm:grid-cols-3 ">
|
|
<.link
|
|
:if={not @restrict_maps_creation?}
|
|
class="card h-[250px] rounded-none bg-gradient-to-l from-stone-950 to-stone-900 hover:text-white transform transition duration-500"
|
|
patch={~p"/maps/new"}
|
|
>
|
|
<div class="card-body justify-center items-center">
|
|
<.icon name="hero-plus-solid" class="w-20 h-20" />
|
|
<h3 class="card-title text-center text-md">Create Map</h3>
|
|
</div>
|
|
</.link>
|
|
<.async_result :let={maps} :if={assigns[:maps]} assign={@maps}>
|
|
<:loading>
|
|
<div class="skeleton card rounded"></div>
|
|
<div class="skeleton card rounded"></div>
|
|
<div class="skeleton card rounded"></div>
|
|
<div class="skeleton card rounded"></div>
|
|
</:loading>
|
|
<:failed :let={reason}>{reason}</:failed>
|
|
<.link
|
|
:for={map <- maps}
|
|
navigate={~p"/#{map.slug}"}
|
|
class="card h-[250px] rounded-none bg-gradient-to-l from-stone-950 to-stone-900 hover:text-white"
|
|
>
|
|
<figure class="absolute z-10 h-200 avatar w-full h-full">
|
|
<img :if={map.scope === :all} class="absolute h-200" src="/images/all_back.webp" />
|
|
<img :if={map.scope === :wormholes} class="absolute h-200" src="/images/wh_back.jpg" />
|
|
<img
|
|
:if={map.scope === :stargates}
|
|
class="absolute h-200"
|
|
src="/images/stargates_back.webp"
|
|
/>
|
|
</figure>
|
|
|
|
<div class="absolute z-50 left-0 top-0 w-full h-full p-6 flex flex-col justify-between bg-opacity-70 bg-neutral-900 hover:bg-opacity-30 transform transition duration-500">
|
|
<div>
|
|
<h2 class="card-title text-sm">
|
|
{map.name}
|
|
</h2>
|
|
<p title={map.description} class="text-sm mt-4 line-clamp-2">
|
|
{map.description}
|
|
</p>
|
|
<div
|
|
:if={WandererApp.Maps.can_view_acls?(map, @current_user)}
|
|
class="w-full flex gap-2 mt-2 text-xs"
|
|
>
|
|
<button
|
|
:for={acl <- map.acls}
|
|
class="p-tag p-component rounded-none hover:text-white"
|
|
id={"map-acl-#{acl.id}"}
|
|
type="button"
|
|
phx-hook="MapAction"
|
|
data-event="open_acl"
|
|
data-data={acl.id}
|
|
>
|
|
<div class="p-tag-value">
|
|
{acl.name}
|
|
</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h2 class="w-full flex justify-between mb-4 text-sm">
|
|
Tracked Characters:
|
|
<span class="font-bold">
|
|
{map.characters_count}
|
|
</span>
|
|
</h2>
|
|
<div class="flex gap-2 justify-end">
|
|
<button
|
|
:if={WandererApp.Maps.can_edit?(map, @current_user)}
|
|
id={"map-characters-#{map.slug}"}
|
|
phx-hook="MapAction"
|
|
data-event="open_characters"
|
|
data-data={map.slug}
|
|
class="h-8 w-8 hover:text-white"
|
|
>
|
|
<.icon name="hero-user-group-solid" class="w-6 h-6" />
|
|
</button>
|
|
<button
|
|
:if={WandererApp.Maps.can_edit?(map, @current_user)}
|
|
id={"map-audit-#{map.slug}"}
|
|
phx-hook="MapAction"
|
|
data-event="open_audit"
|
|
data-data={map.slug}
|
|
class="h-8 w-8 hover:text-white"
|
|
>
|
|
<.icon name="hero-key-solid" class="w-6 h-6" />
|
|
</button>
|
|
<button
|
|
:if={WandererApp.Maps.can_edit?(map, @current_user)}
|
|
id={"map-settings-#{map.slug}"}
|
|
phx-hook="MapAction"
|
|
data-event="open_settings"
|
|
data-data={map.slug}
|
|
class="h-8 w-8 hover:text-white"
|
|
>
|
|
<.icon name="hero-cog-6-tooth-solid" class="w-6 h-6" />
|
|
</button>
|
|
<button
|
|
:if={WandererApp.Maps.can_edit?(map, @current_user)}
|
|
id={"edit-map-#{map.slug}"}
|
|
class="h-8 w-8 hover:text-white"
|
|
type="button"
|
|
phx-hook="MapAction"
|
|
data-event="edit_map"
|
|
data-data={map.slug}
|
|
>
|
|
<.icon name="hero-pencil-square-solid" class="w-6 h-6" />
|
|
</button>
|
|
<button
|
|
:if={WandererApp.Maps.can_edit?(map, @current_user)}
|
|
id={"delete-map-#{map.slug}"}
|
|
class="h-8 w-8 hover:text-white"
|
|
phx-hook="MapAction"
|
|
data-event="delete"
|
|
data-data={map.slug}
|
|
data-confirm="Please confirm to delete map!"
|
|
>
|
|
<.icon name="hero-trash-solid" class="w-6 h-6" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</.link>
|
|
</.async_result>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<.modal
|
|
:if={@is_connected? && @live_action in [:create, :edit]}
|
|
title={"#{(@live_action == :create && "Create") || "Edit"} Map"}
|
|
class="!w-[500px]"
|
|
id="add_map_modal"
|
|
show
|
|
on_cancel={JS.patch(~p"/maps")}
|
|
>
|
|
<.form :let={f} for={@form} phx-change="validate" phx-submit={@live_action} autocomplete="off">
|
|
<.input type="text" field={f[:name]} placeholder="Name" />
|
|
<.input type="text" field={f[:slug]} prefix={@uri} placeholder="map-slug" />
|
|
<.input type="textarea" field={f[:description]} placeholder="Public description" />
|
|
<.input
|
|
type="select"
|
|
field={f[:owner_id]}
|
|
class="select h-8 min-h-[10px] !pt-1 !pb-1 text-sm bg-neutral-900"
|
|
wrapper_class="mt-2"
|
|
label="Map owner"
|
|
placeholder="Select a map owner"
|
|
options={Enum.map(@characters, fn character -> {character.label, character.id} end)}
|
|
/>
|
|
<!-- Map Scopes Section -->
|
|
<div class="mt-2 border border-dashed border-stone-600 rounded p-3">
|
|
<p class="text-xs text-stone-400 mb-2">
|
|
Select which space types to automatically track on the map
|
|
</p>
|
|
<div class="grid grid-cols-2 gap-1">
|
|
<%= for scope_option <- @available_scopes do %>
|
|
<% is_checked = scope_option.value in (get_current_scopes(f) || []) %>
|
|
<label class="flex items-center gap-2 cursor-pointer py-1 px-2 rounded hover:bg-stone-800">
|
|
<div class="flex items-center">
|
|
<div
|
|
class={[
|
|
"checkboxRoot sizeM p-checkbox p-component",
|
|
if(is_checked, do: "p-highlight", else: "")
|
|
]}
|
|
data-p-highlight={is_checked}
|
|
data-p-disabled="false"
|
|
data-pc-name="checkbox"
|
|
data-pc-section="root"
|
|
>
|
|
<input
|
|
type="checkbox"
|
|
name={"form[scopes][#{scope_option.value}]"}
|
|
value="true"
|
|
checked={is_checked}
|
|
class="p-checkbox-input"
|
|
aria-invalid="false"
|
|
data-pc-section="input"
|
|
/>
|
|
<div
|
|
class="p-checkbox-box"
|
|
data-p-highlight={is_checked}
|
|
data-p-disabled="false"
|
|
data-pc-section="box"
|
|
>
|
|
<svg
|
|
:if={is_checked}
|
|
width="14"
|
|
height="14"
|
|
viewBox="0 0 14 14"
|
|
fill="none"
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="p-icon p-checkbox-icon"
|
|
aria-hidden="true"
|
|
data-pc-section="icon"
|
|
>
|
|
<path
|
|
d="M4.86199 11.5948C4.78717 11.5923 4.71366 11.5745 4.64596 11.5426C4.57826 11.5107 4.51779 11.4652 4.46827 11.4091L0.753985 7.69483C0.683167 7.64891 0.623706 7.58751 0.580092 7.51525C0.536478 7.44299 0.509851 7.36177 0.502221 7.27771C0.49459 7.19366 0.506156 7.10897 0.536046 7.03004C0.565935 6.95111 0.613367 6.88 0.674759 6.82208C0.736151 6.76416 0.8099 6.72095 0.890436 6.69571C0.970973 6.67046 1.05619 6.66385 1.13966 6.67635C1.22313 6.68886 1.30266 6.72017 1.37226 6.76792C1.44186 6.81567 1.4997 6.8786 1.54141 6.95197L4.86199 10.2503L12.6397 2.49483C12.7444 2.42694 12.8689 2.39617 12.9932 2.40745C13.1174 2.41873 13.2343 2.47141 13.3251 2.55705C13.4159 2.64268 13.4753 2.75632 13.4938 2.87973C13.5123 3.00315 13.4888 3.1292 13.4271 3.23768L5.2557 11.4091C5.20618 11.4652 5.14571 11.5107 5.07801 11.5426C5.01031 11.5745 4.9368 11.5923 4.86199 11.5948Z"
|
|
fill="currentColor"
|
|
>
|
|
</path>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<span class="text-xs select-none">{scope_option.label}</span>
|
|
</label>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:only_tracked_characters]}
|
|
label="Allow only tracked characters"
|
|
/>
|
|
<.input
|
|
:if={@live_action == :create}
|
|
type="checkbox"
|
|
field={f[:create_default_acl]}
|
|
label="Create default access list"
|
|
checked={
|
|
Phoenix.HTML.Form.normalize_value("checkbox", f[:create_default_acl].value) == true or
|
|
is_nil(f[:create_default_acl].value)
|
|
}
|
|
/>
|
|
<.live_select
|
|
field={f[:acls]}
|
|
dropdown_extra_class="!h-24"
|
|
value_mapper={&map_acl_value/1}
|
|
debounce={250}
|
|
update_min_len={2}
|
|
mode={:tags}
|
|
options={@acls}
|
|
placeholder="Add an existing access list"
|
|
/>
|
|
<div class="modal-action">
|
|
<.button class="mt-2" type="submit">
|
|
{(@live_action == :create && "Create") || "Save"}
|
|
</.button>
|
|
</div>
|
|
</.form>
|
|
</.modal>
|
|
|
|
<.modal
|
|
:if={@live_action in [:settings] && not is_nil(assigns[:map])}
|
|
title="Map Settings"
|
|
class="!min-w-[700px]"
|
|
id="map-settings-modal"
|
|
show
|
|
on_cancel={JS.patch(~p"/maps")}
|
|
>
|
|
<div class="flex flex-col gap-3">
|
|
<div class="flex flex-col gap-2">
|
|
<div class="verticalTabsContainer">
|
|
<div class="p-tabview p-component" data-pc-name="tabview" data-pc-section="root">
|
|
<div class="p-tabview-nav-container" data-pc-section="navcontainer">
|
|
<div class="p-tabview-nav-content" data-pc-section="navcontent">
|
|
<ul class="p-tabview-nav" role="tablist" data-pc-section="nav">
|
|
<li
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes("p-tabview-selected p-highlight": @active_settings_tab == "general")
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="0"
|
|
aria-controls="pr_id_330_content"
|
|
aria-selected="true"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="general"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-wrench-screwdriver-solid" class="w-4 h-4" /> General
|
|
</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li
|
|
:if={@map_subscriptions_enabled?}
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes("p-tabview-selected p-highlight": @active_settings_tab == "balance")
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="-1"
|
|
aria-controls="pr_id_332_content"
|
|
aria-selected="false"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="balance"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-banknotes-solid" class="w-4 h-4" /> Balance
|
|
</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li
|
|
:if={@map_subscriptions_enabled?}
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes(
|
|
"p-tabview-selected p-highlight": @active_settings_tab == "subscription"
|
|
)
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="-1"
|
|
aria-controls="pr_id_334_content"
|
|
aria-selected="false"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="subscription"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-check-badge-solid" class="w-4 h-4" /> Subscription
|
|
</span>
|
|
</a>
|
|
</li>
|
|
|
|
<li
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes("p-tabview-selected p-highlight": @active_settings_tab == "import")
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="-1"
|
|
aria-controls="pr_id_331_content"
|
|
aria-selected="false"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="import"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-document-arrow-down-solid" class="w-4 h-4" /> Import/Export
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li
|
|
:if={not WandererApp.Env.public_api_disabled?()}
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes(
|
|
"p-tabview-selected p-highlight": @active_settings_tab == "public_api"
|
|
)
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="-1"
|
|
aria-controls="pr_id_335_content"
|
|
aria-selected="false"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="public_api"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-globe-alt-solid" class="w-4 h-4" /> Public Api
|
|
</span>
|
|
</a>
|
|
</li>
|
|
<li
|
|
:if={@map_subscriptions_enabled?}
|
|
class={[
|
|
"p-unselectable-text",
|
|
classes("p-tabview-selected p-highlight": @active_settings_tab == "bot")
|
|
]}
|
|
role="presentation"
|
|
data-pc-name=""
|
|
data-pc-section="header"
|
|
>
|
|
<a
|
|
role="tab"
|
|
class="p-tabview-nav-link flex p-[10px]"
|
|
tabindex="-1"
|
|
aria-controls="pr_id_335_content"
|
|
aria-selected="false"
|
|
aria-disabled="false"
|
|
data-pc-section="headeraction"
|
|
phx-click="change_settings_tab"
|
|
phx-value-tab="bot"
|
|
>
|
|
<span class="p-tabview-title" data-pc-section="headertitle">
|
|
<.icon name="hero-puzzle-piece-solid" class="w-4 h-4" /> Bots
|
|
</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="p-tabview-panels" data-pc-section="panelcontainer">
|
|
<div
|
|
id="pr_id_330_content"
|
|
class="p-tabview-panel"
|
|
role="tabpanel"
|
|
aria-labelledby="pr_id_33_header_0"
|
|
data-pc-name=""
|
|
data-pc-section="content"
|
|
>
|
|
<div :if={@active_settings_tab == "general"}>
|
|
<.form
|
|
:let={f}
|
|
:if={assigns |> Map.get(:options_form, false)}
|
|
for={@options_form}
|
|
phx-change="update_options"
|
|
>
|
|
<.input
|
|
type="select"
|
|
field={f[:layout]}
|
|
class="select h-8 min-h-[10px] !pt-1 !pb-1 text-sm bg-neutral-900"
|
|
label="Map systems layout"
|
|
placeholder="Map default layout"
|
|
options={@layout_options}
|
|
/>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:store_custom_labels]}
|
|
label="Store system custom labels"
|
|
/>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:show_temp_system_name]}
|
|
label="Allow temporary system names"
|
|
/>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:show_linked_signature_id]}
|
|
label="Show linked signature ID as custom label part"
|
|
/>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:show_linked_signature_id_temp_name]}
|
|
label="Show linked signature ID as temporary name part"
|
|
/>
|
|
<.input
|
|
type="checkbox"
|
|
field={f[:restrict_offline_showing]}
|
|
label="Show offline characters to admins & managers only"
|
|
/>
|
|
<.input
|
|
type="select"
|
|
field={f[:allowed_copy_for]}
|
|
class="select h-8 min-h-[10px] !pt-1 !pb-1 text-sm bg-neutral-900"
|
|
label="Copy map data allowed for"
|
|
placeholder="Select role to allow map data copy"
|
|
options={@allowed_copy_for_options}
|
|
/>
|
|
<.input
|
|
type="select"
|
|
field={f[:allowed_paste_for]}
|
|
class="select h-8 min-h-[10px] !pt-1 !pb-1 text-sm bg-neutral-900"
|
|
label="Paste map data allowed for"
|
|
placeholder="Select role to allow map data paste"
|
|
options={@allowed_paste_for_options}
|
|
/>
|
|
</.form>
|
|
</div>
|
|
|
|
<div :if={@active_settings_tab == "import"}>
|
|
<.form
|
|
:if={assigns |> Map.get(:import_form, false)}
|
|
for={@import_form}
|
|
phx-change="import"
|
|
>
|
|
<%!-- <div phx-drop-target="{@uploads.settings.ref}">
|
|
<.live_file_input upload={@uploads.settings} />
|
|
</div> --%>
|
|
</.form>
|
|
<progress :if={@importing} class="progress w-56"></progress>
|
|
<.button
|
|
id="export-settings-btn"
|
|
class="mt-8"
|
|
type="button"
|
|
disabled={@importing}
|
|
phx-hook="DownloadJson"
|
|
data-name={@map_slug}
|
|
data-content={Jason.encode!(assigns[:export_settings] || %{})}
|
|
>
|
|
<.icon name="hero-document-arrow-down-solid" class="w-4 h-4" /> Export Settings
|
|
</.button>
|
|
</div>
|
|
|
|
<div :if={@active_settings_tab == "bot"}>
|
|
<h3 class="text-lg font-semibold mb-2">Bots Integration</h3>
|
|
<div class="mb-6 p-4 border rounded-md">
|
|
<p class="mb-2">
|
|
The bot license allows you to integrate your map with automated tools and bots.
|
|
Here's how to use it:
|
|
</p>
|
|
<ol class="list-decimal pl-5 mb-4 space-y-2">
|
|
<li>Create a license key below (requires an active subscription)</li>
|
|
<li>Use the license key to authenticate your bot with our API</li>
|
|
<%!-- <li>
|
|
Make API calls to <code class="bg-gray-800 px-1 py-0.5 rounded">GET /api/license/validate</code>
|
|
with the license key as a Bearer token in the Authorization header
|
|
</li>
|
|
<li>
|
|
If valid, you'll receive the map ID which you can use for other API endpoints
|
|
</li> --%>
|
|
</ol>
|
|
<p class="text-sm text-gray-600">
|
|
For detailed API documentation, please refer to our <a
|
|
href="/license"
|
|
class="text-blue-600 hover:underline"
|
|
>API documentation</a>.
|
|
</p>
|
|
</div>
|
|
|
|
<.live_component
|
|
module={WandererAppWeb.Maps.LicenseComponent}
|
|
id="license-component"
|
|
map_id={@map.id}
|
|
/>
|
|
</div>
|
|
|
|
<div
|
|
:if={
|
|
@active_settings_tab == "public_api" and
|
|
not WandererApp.Env.public_api_disabled?()
|
|
}
|
|
class="p-6"
|
|
>
|
|
<h2 class="text-lg font-semibold mb-4">Public API</h2>
|
|
<div class="flex flex-col gap-3 items-start w-full">
|
|
<div>
|
|
<input
|
|
:if={not is_nil(@public_api_key)}
|
|
class="input input-bordered text-sm truncate bg-neutral-800 text-white w-[350px]"
|
|
readonly
|
|
type="text"
|
|
value={@public_api_key}
|
|
/>
|
|
<input
|
|
:if={is_nil(@public_api_key)}
|
|
class="input input-bordered text-sm truncate bg-neutral-800 text-gray-400 w-[350px]"
|
|
readonly
|
|
type="text"
|
|
placeholder="No Public API Key yet"
|
|
/>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<.button
|
|
type="button"
|
|
phx-click="generate-map-api-key"
|
|
class="p-button p-component p-button-primary"
|
|
style="min-width: 120px;"
|
|
>
|
|
<span class="p-button-label">Generate</span>
|
|
</.button>
|
|
<.button
|
|
type="button"
|
|
phx-hook="CopyToClipboard"
|
|
id="copy-map-api-key"
|
|
data-url={@public_api_key}
|
|
disabled={is_nil(@public_api_key)}
|
|
class={"p-button p-component " <> if(is_nil(@public_api_key), do: "p-disabled", else: "")}
|
|
>
|
|
<span class="p-button-label">Copy</span>
|
|
</.button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border-t border-stone-700 mt-4 pt-4">
|
|
<h3 class="text-md font-semibold mb-3">Server-Sent Events (SSE)</h3>
|
|
<div class="flex items-center gap-3">
|
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
<input
|
|
type="checkbox"
|
|
class="checkbox checkbox-primary"
|
|
checked={@sse_enabled}
|
|
phx-click="toggle-sse"
|
|
/>
|
|
<span>Enable SSE for this map</span>
|
|
</label>
|
|
</div>
|
|
<p class="text-sm text-stone-400 mt-2">
|
|
When enabled, external clients can subscribe to real-time map events via SSE.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<.live_component
|
|
:if={@active_settings_tab == "balance"}
|
|
module={WandererAppWeb.Maps.MapBalanceComponent}
|
|
id="map-balance-component"
|
|
map_id={@map.id}
|
|
notify_to={self()}
|
|
event_name="balance_event"
|
|
current_user={@current_user}
|
|
/>
|
|
|
|
<.live_component
|
|
:if={@active_settings_tab == "subscription"}
|
|
module={WandererAppWeb.Maps.MapSubscriptionsComponent}
|
|
id="map-subscriptions-component"
|
|
map_id={@map.id}
|
|
notify_to={self()}
|
|
event_name="subscriptions_event"
|
|
current_user={@current_user}
|
|
readonly={false}
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-action"></div>
|
|
</.modal>
|