From da770f121fa5f61bb8bc593df8d829d6f9bfabbc Mon Sep 17 00:00:00 2001 From: Jamey Greenwood Date: Tue, 30 Dec 2025 21:53:52 +0000 Subject: [PATCH] feat: add Theme LiveView with preset switching MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implement basic theme editor interface with live preview: - ThemeLive.Index LiveView with mount and event handlers - Two-column layout: controls sidebar + preview area - Display all 9 presets as clickable buttons - Apply preset and regenerate CSS on click - Show current theme settings (mood, typography, shape, density, color) - Preview page switcher (7 pages: home, collection, product, cart, about, contact, 404) - Inline + +
+

+ Preview: <%= String.capitalize(to_string(@preview_page)) %> +

+ +
+

+ This is a preview of the <%= @preview_page %> page with your current theme settings. +

+ +
+ + +
+ +
+

+ Card Example +

+

+ This card demonstrates the current surface, border, and text colors with the selected shape style. +

+
+ +
+ Detailed preview pages coming in Phase 5 +
+
+
+ + + + + diff --git a/lib/simpleshop_theme_web/router.ex b/lib/simpleshop_theme_web/router.ex index 7c00be0..77496d0 100644 --- a/lib/simpleshop_theme_web/router.ex +++ b/lib/simpleshop_theme_web/router.ex @@ -54,6 +54,7 @@ defmodule SimpleshopThemeWeb.Router do on_mount: [{SimpleshopThemeWeb.UserAuth, :require_authenticated}] do live "/users/settings", UserLive.Settings, :edit live "/users/settings/confirm-email/:token", UserLive.Settings, :confirm_email + live "/admin/theme", ThemeLive.Index, :index end post "/users/update-password", UserSessionController, :update_password diff --git a/test/simpleshop_theme_web/live/theme_live_test.exs b/test/simpleshop_theme_web/live/theme_live_test.exs new file mode 100644 index 0000000..bb839c0 --- /dev/null +++ b/test/simpleshop_theme_web/live/theme_live_test.exs @@ -0,0 +1,118 @@ +defmodule SimpleshopThemeWeb.ThemeLiveTest do + use SimpleshopThemeWeb.ConnCase, async: false + + import Phoenix.LiveViewTest + import SimpleshopTheme.AccountsFixtures + + alias SimpleshopTheme.Settings + + setup do + user = user_fixture() + %{user: user} + end + + describe "Index (unauthenticated)" do + test "redirects to login when not authenticated", %{conn: conn} do + {:error, redirect} = live(conn, ~p"/admin/theme") + + assert {:redirect, %{to: path}} = redirect + assert path == ~p"/users/log-in" + end + end + + describe "Index (authenticated)" do + setup %{conn: conn, user: user} do + conn = log_in_user(conn, user) + %{conn: conn} + end + + test "renders theme editor page", %{conn: conn} do + {:ok, _view, html} = live(conn, ~p"/admin/theme") + + assert html =~ "Theme Editor" + assert html =~ "Save Theme" + assert html =~ "Presets" + end + + test "displays all 9 presets", %{conn: conn} do + {:ok, _view, html} = live(conn, ~p"/admin/theme") + + assert html =~ "gallery" + assert html =~ "studio" + assert html =~ "boutique" + assert html =~ "bold" + assert html =~ "playful" + assert html =~ "minimal" + assert html =~ "night" + assert html =~ "classic" + assert html =~ "impulse" + end + + test "displays current theme settings", %{conn: conn} do + {:ok, _settings} = Settings.apply_preset(:gallery) + {:ok, _view, html} = live(conn, ~p"/admin/theme") + + assert html =~ "warm" + assert html =~ "editorial" + assert html =~ "soft" + assert html =~ "spacious" + end + + test "displays generated CSS in preview", %{conn: conn} do + {:ok, _view, html} = live(conn, ~p"/admin/theme") + + assert html =~ ".preview-frame, .shop-root" + assert html =~ "--t-accent-h:" + assert html =~ "--t-surface-base:" + assert html =~ "--t-font-heading:" + end + + test "applies preset and updates preview", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/admin/theme") + + html = + view + |> element("button", "gallery") + |> render_click() + + theme_settings = Settings.get_theme_settings() + assert theme_settings.mood == "warm" + assert theme_settings.typography == "editorial" + assert html =~ "warm" + assert html =~ "editorial" + end + + test "switches preview page", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/admin/theme") + + html = + view + |> element("button", "Collection") + |> render_click() + + assert html =~ "Preview: Collection" + end + + test "save theme button works", %{conn: conn} do + {:ok, view, _html} = live(conn, ~p"/admin/theme") + + view + |> element("button", "Save Theme") + |> render_click() + + assert view |> element("button", "Save Theme") |> has_element?() + end + + test "all preview page buttons are present", %{conn: conn} do + {:ok, _view, html} = live(conn, ~p"/admin/theme") + + assert html =~ "Home" + assert html =~ "Collection" + assert html =~ "Product" + assert html =~ "Cart" + assert html =~ "About" + assert html =~ "Contact" + assert html =~ "404" + end + end +end