Adds a full-screen map view rendering every Good rover-location as a green circle marker (popup links to the detail page). Uses the standard OSM/Satellite + Maidenhead grid overlay pattern. Bad locations are excluded. Adds a Map button next to Add location on the index header.
68 lines
1.7 KiB
Elixir
68 lines
1.7 KiB
Elixir
defmodule MicrowavepropWeb.RoverLocationsLive.Map do
|
|
@moduledoc """
|
|
`/rover-locations/map` — full-screen map of every rover-location
|
|
marked Good. Each marker links to its detail page.
|
|
"""
|
|
use MicrowavepropWeb, :live_view
|
|
|
|
import Ecto.Query
|
|
|
|
alias Microwaveprop.Radio.Maidenhead
|
|
alias Microwaveprop.Repo
|
|
alias Microwaveprop.Rover.Location
|
|
|
|
@impl true
|
|
def mount(_params, _session, socket) do
|
|
points =
|
|
Location
|
|
|> where([l], l.status == :good)
|
|
|> Repo.all()
|
|
|> Enum.map(&point_payload/1)
|
|
|
|
{:ok,
|
|
assign(socket,
|
|
page_title: "Rover Locations Map",
|
|
points: points,
|
|
points_json: Jason.encode!(points)
|
|
)}
|
|
end
|
|
|
|
defp point_payload(%Location{} = loc) do
|
|
%{
|
|
id: loc.id,
|
|
lat: loc.lat,
|
|
lon: loc.lon,
|
|
grid: Maidenhead.from_latlon(loc.lat, loc.lon, 6),
|
|
notes: loc.notes
|
|
}
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<Layouts.app flash={@flash} current_scope={@current_scope} max_width="max-w-7xl">
|
|
<.header>
|
|
Rover Locations Map
|
|
<:subtitle>
|
|
{length(@points)} good location{if length(@points) == 1, do: "", else: "s"} —
|
|
click a marker for details.
|
|
</:subtitle>
|
|
<:actions>
|
|
<.link navigate={~p"/rover-locations"} class="btn btn-ghost btn-sm">
|
|
<.icon name="hero-list-bullet" class="w-4 h-4" /> List
|
|
</.link>
|
|
</:actions>
|
|
</.header>
|
|
|
|
<div
|
|
id="rover-locations-map"
|
|
phx-hook="RoverLocationsMap"
|
|
phx-update="ignore"
|
|
data-points={@points_json}
|
|
class="h-[75vh] rounded border border-base-300 z-0"
|
|
>
|
|
</div>
|
|
</Layouts.app>
|
|
"""
|
|
end
|
|
end
|