defmodule AprsmeWeb.ThemeManager do @moduledoc """ Server-side theme management for better performance and consistency. Moves theme logic from JavaScript to LiveView to: - Reduce client-side complexity - Provide server-side theme state management - Enable theme persistence across page loads - Improve performance by eliminating JavaScript theme detection """ use Phoenix.Component @themes ~w(light dark auto) @default_theme "auto" @doc """ Initializes theme from session/user preferences. Call this from your LiveView's mount/3 callback. """ def init_theme(socket, session \\ %{}) do theme = get_stored_theme(session) resolved_theme = resolve_theme(theme, get_system_preference()) Phoenix.Component.assign(socket, %{ theme: theme, resolved_theme: resolved_theme, theme_colors: get_theme_colors(resolved_theme) }) end @doc """ Handles theme change events from the client. Call this from your LiveView's handle_event/3 callback. """ def handle_theme_change(socket, theme) when theme in @themes do resolved_theme = resolve_theme(theme, get_system_preference()) # Store theme preference (could be extended to user preferences) # For now, we'll use session storage socket |> Phoenix.Component.assign(%{ theme: theme, resolved_theme: resolved_theme, theme_colors: get_theme_colors(resolved_theme) }) |> Phoenix.LiveView.push_event("update_theme", %{ theme: theme, resolved_theme: resolved_theme, colors: get_theme_colors(resolved_theme) }) end def handle_theme_change(socket, _invalid_theme), do: socket @doc """ Resolves 'auto' theme based on system preference. """ def resolve_theme("auto", system_preference), do: system_preference def resolve_theme(theme, _system_preference) when theme in ["light", "dark"], do: theme def resolve_theme(_invalid, system_preference), do: system_preference @doc """ Gets theme colors for charts and components. """ def get_theme_colors("dark") do %{ text: "#e5e7eb", grid: "#374151", background: "rgba(0, 0, 0, 0.1)", primary: "#3b82f6", secondary: "#8b5cf6", accent: "#06b6d4" } end def get_theme_colors(_light_or_other) do %{ text: "#111827", grid: "#9ca3af", background: "rgba(255, 255, 255, 0.1)", primary: "#2563eb", secondary: "#7c3aed", accent: "#0891b2" } end # Gets stored theme from session or defaults to auto. defp get_stored_theme(%{"theme" => theme}) when theme in @themes, do: theme defp get_stored_theme(_session), do: @default_theme # Gets system theme preference (defaults to light for server-side). # In a real implementation, this could be determined from user agent # or stored in user preferences. defp get_system_preference, do: "light" @doc """ Component for theme selector. """ attr :theme, :string, required: true attr :class, :string, default: "" def theme_selector(assigns) do ~H"""
""" end end