feat: move theme selector to user settings, remove from nav
Add an Appearance section to the Personal tab in user settings with three clearly labelled options (Auto/Light/Dark). A ThemeSelector hook reads localStorage to highlight the active choice and updates it when selection changes. Remove the dropdown toggle from both the main nav and admin nav.
This commit is contained in:
parent
2beadb0dc7
commit
7f11a890a8
3 changed files with 83 additions and 4 deletions
|
|
@ -1375,10 +1375,30 @@ const StatusTitle = {
|
|||
}
|
||||
}
|
||||
|
||||
const ThemeSelector = {
|
||||
mounted() {
|
||||
this.updateActive()
|
||||
window.addEventListener("phx:set-theme", () => this.updateActive())
|
||||
},
|
||||
updateActive() {
|
||||
const current = localStorage.getItem("phx:theme") || "system"
|
||||
this.el.querySelectorAll<HTMLElement>("[data-phx-theme]").forEach((btn) => {
|
||||
const isActive = btn.dataset.phxTheme === current
|
||||
btn.setAttribute("aria-pressed", isActive ? "true" : "false")
|
||||
btn.classList.toggle("ring-2", isActive)
|
||||
btn.classList.toggle("ring-indigo-500", isActive)
|
||||
btn.classList.toggle("bg-indigo-50", isActive)
|
||||
btn.classList.toggle("dark:bg-indigo-900/20", isActive)
|
||||
btn.classList.toggle("text-indigo-700", isActive)
|
||||
btn.classList.toggle("dark:text-indigo-300", isActive)
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
const liveSocket = new LiveSocket("/live", Socket, {
|
||||
longPollFallbackMs: 5000,
|
||||
params: { _csrf_token: csrfToken, timezone: userTimezone },
|
||||
hooks: { ...colocatedHooks, SensorChart, CopyToClipboard, ScrollToTop, AutoDismissFlash, BetaBannerDismiss, NetworkMap, SitesMap, LeafletMap, DeviceListReorder, MikrotikPortSync, GlobalSearch, GlobalSearchTrigger, DynamicFavicon, StatusTitle },
|
||||
hooks: { ...colocatedHooks, SensorChart, CopyToClipboard, ScrollToTop, AutoDismissFlash, BetaBannerDismiss, NetworkMap, SitesMap, LeafletMap, DeviceListReorder, MikrotikPortSync, GlobalSearch, GlobalSearchTrigger, DynamicFavicon, StatusTitle, ThemeSelector },
|
||||
})
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
|
|
|
|||
|
|
@ -444,8 +444,6 @@ defmodule ToweropsWeb.Layouts do
|
|||
<.icon name="hero-question-mark-circle" class="h-5 w-5" />
|
||||
</.link>
|
||||
|
||||
<.theme_toggle />
|
||||
|
||||
<!-- User menu -->
|
||||
<button
|
||||
type="button"
|
||||
|
|
@ -977,7 +975,6 @@ defmodule ToweropsWeb.Layouts do
|
|||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-1 sm:gap-2">
|
||||
<.theme_toggle />
|
||||
<.link
|
||||
navigate={~p"/orgs"}
|
||||
class="text-xs sm:text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
|
||||
|
|
|
|||
|
|
@ -394,6 +394,68 @@
|
|||
</.form>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- Appearance Section -->
|
||||
<%= if @active_tab == "personal" do %>
|
||||
<div class="grid max-w-7xl grid-cols-1 gap-x-8 gap-y-10 px-4 py-16 sm:px-6 md:grid-cols-3 lg:px-8">
|
||||
<div>
|
||||
<h2 class="text-base/7 font-semibold text-gray-900 dark:text-white">
|
||||
{t("Appearance")}
|
||||
</h2>
|
||||
<p class="mt-1 text-sm/6 text-gray-500 dark:text-gray-400">
|
||||
{t("Choose your preferred interface theme.")}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="md:col-span-2">
|
||||
<div
|
||||
id="theme-selector"
|
||||
phx-hook="ThemeSelector"
|
||||
phx-update="ignore"
|
||||
class="flex gap-3"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed="false"
|
||||
data-phx-theme="system"
|
||||
phx-click={JS.dispatch("phx:set-theme")}
|
||||
class="flex flex-1 flex-col items-center gap-2 rounded-lg border border-gray-200 px-4 py-5 text-sm font-medium text-gray-700 transition-colors hover:border-indigo-300 hover:bg-indigo-50 dark:border-white/10 dark:text-gray-300 dark:hover:border-indigo-500 dark:hover:bg-indigo-900/20"
|
||||
>
|
||||
<.icon name="hero-computer-desktop" class="h-6 w-6" />
|
||||
{t("Auto")}
|
||||
<span class="text-xs font-normal text-gray-400 dark:text-gray-500">
|
||||
{t("System default")}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed="false"
|
||||
data-phx-theme="light"
|
||||
phx-click={JS.dispatch("phx:set-theme")}
|
||||
class="flex flex-1 flex-col items-center gap-2 rounded-lg border border-gray-200 px-4 py-5 text-sm font-medium text-gray-700 transition-colors hover:border-indigo-300 hover:bg-indigo-50 dark:border-white/10 dark:text-gray-300 dark:hover:border-indigo-500 dark:hover:bg-indigo-900/20"
|
||||
>
|
||||
<.icon name="hero-sun" class="h-6 w-6" />
|
||||
{t("Light")}
|
||||
<span class="text-xs font-normal text-gray-400 dark:text-gray-500">
|
||||
{t("Always light")}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
aria-pressed="false"
|
||||
data-phx-theme="dark"
|
||||
phx-click={JS.dispatch("phx:set-theme")}
|
||||
class="flex flex-1 flex-col items-center gap-2 rounded-lg border border-gray-200 px-4 py-5 text-sm font-medium text-gray-700 transition-colors hover:border-indigo-300 hover:bg-indigo-50 dark:border-white/10 dark:text-gray-300 dark:hover:border-indigo-500 dark:hover:bg-indigo-900/20"
|
||||
>
|
||||
<.icon name="hero-moon" class="h-6 w-6" />
|
||||
{t("Dark")}
|
||||
<span class="text-xs font-normal text-gray-400 dark:text-gray-500">
|
||||
{t("Always dark")}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<!-- Account Tab -->
|
||||
<%= if @active_tab == "account" do %>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue