diff --git a/internal/core/templates/console.html b/internal/core/templates/console.html
index 53b506c..24697f9 100644
--- a/internal/core/templates/console.html
+++ b/internal/core/templates/console.html
@@ -14,17 +14,25 @@
{{/* Confirm/location prompts. Connecting the modem sends a signed login that
-confirms access (server-side); these banners reflect the state at page load and
-are hidden live by console.js once a confirmed/location status arrives. */}}
+confirms access (server-side). These reflect the state at page load; console.js
+then updates them live — hiding the confirm prompt and revealing the location
+prompt once a "confirmed" status arrives, and hiding the location prompt once a
+"location" status arrives. The location prompt is always rendered when no
+location is stored (hidden until the repeater is confirmed with admin) so the
+swap needs no new markup. The flex row is nested so the [hidden] attribute wins
+(Bootstrap's .d-flex is display:flex !important and would otherwise show it). */}}
{{if not .Repeater.Confirmed}}
This repeater hasn't been confirmed yet. Connect your modem below — MeshTender will send a signed login
to verify it has access. Confirming happens automatically as soon as the repeater replies.
-{{else if and .Repeater.IsAdmin (not .Repeater.Latitude)}}
-
-
This repeater is confirmed, but its location isn't known yet.
-
+{{end}}
+{{if not .Repeater.Latitude}}
+
+
+
This repeater's location isn't known yet.
+
+
{{end}}
diff --git a/internal/e2e/console_confirm_test.go b/internal/e2e/console_confirm_test.go
index be306c6..32caeff 100644
--- a/internal/e2e/console_confirm_test.go
+++ b/internal/e2e/console_confirm_test.go
@@ -32,8 +32,9 @@ func TestE2EConsoleConfirmBanner(t *testing.T) {
bctx, cancel, watch := startBrowser(t)
defer cancel()
- // --- unconfirmed: confirm-banner present, location-banner absent ---
- var confirmBanner, locBannerA bool
+ // --- unconfirmed: confirm-banner visible; location-banner present but hidden
+ // (it's revealed live by console.js once the repeater confirms with admin) ---
+ var confirmBanner, locBannerHidden bool
if err := chromedp.Run(bctx,
network.Enable(),
cdplog.Enable(),
@@ -41,15 +42,17 @@ func TestE2EConsoleConfirmBanner(t *testing.T) {
chromedp.Navigate(srv.appURL+"/repeaters/"+unconfirmed.PublicID+"/console"),
chromedp.WaitVisible(`[data-testid="allowed-commands"]`, chromedp.ByQuery),
chromedp.Evaluate(`!!document.querySelector('[data-testid="confirm-banner"]')`, &confirmBanner),
- chromedp.Evaluate(`!!document.querySelector('[data-testid="location-banner"]')`, &locBannerA),
+ // Computed display must be none — guards the Bootstrap gotcha where .d-flex
+ // (display:flex !important) would override the [hidden] attribute.
+ chromedp.Evaluate(`(function () { var b = document.querySelector('[data-testid="location-banner"]'); return !!b && getComputedStyle(b).display === 'none'; })()`, &locBannerHidden),
); err != nil {
t.Fatalf("browser run (unconfirmed): %v", err)
}
if !confirmBanner {
t.Error("unconfirmed repeater console is missing the confirm banner")
}
- if locBannerA {
- t.Error("unconfirmed repeater console should not show the location banner")
+ if !locBannerHidden {
+ t.Error("unconfirmed repeater console should render the location banner hidden (revealed after confirm)")
}
// --- confirmed, no location: location-banner + fetch button, no confirm banner ---
diff --git a/internal/web/static/console.js b/internal/web/static/console.js
index 907766f..536be21 100644
--- a/internal/web/static/console.js
+++ b/internal/web/static/console.js
@@ -181,8 +181,13 @@
document.addEventListener("mesh:status", (ev) => {
const state = ev.detail && ev.detail.state;
if (state === "confirmed") {
- const b = document.querySelector('[data-testid="confirm-banner"]');
- if (b) b.hidden = true;
+ // Admin login just confirmed the repeater: drop the "not confirmed" prompt
+ // and reveal the location prompt (rendered hidden when no location is
+ // stored). If a location is already known the prompt isn't in the DOM.
+ const confirmBanner = document.querySelector('[data-testid="confirm-banner"]');
+ if (confirmBanner) confirmBanner.hidden = true;
+ const locationBanner = document.querySelector('[data-testid="location-banner"]');
+ if (locationBanner) locationBanner.hidden = false;
}
if (state === "location") {
const b = document.querySelector('[data-testid="location-banner"]');