From 73f69a72a5c8f9eddf5e64ac80749e18fff9b66b Mon Sep 17 00:00:00 2001 From: KKlochko Date: Thu, 3 Apr 2025 21:46:59 +0300 Subject: [PATCH] Add the BookSearch component. --- .../components/my_components.ex | 1 + .../components/my_components/book_search.ex | 95 +++++++++++++++++++ .../live/book_live/index.ex | 50 +++++++++- 3 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 lib/decentralised_book_index_web/components/my_components/book_search.ex diff --git a/lib/decentralised_book_index_web/components/my_components.ex b/lib/decentralised_book_index_web/components/my_components.ex index 698b05f..948502d 100644 --- a/lib/decentralised_book_index_web/components/my_components.ex +++ b/lib/decentralised_book_index_web/components/my_components.ex @@ -4,6 +4,7 @@ defmodule DecentralisedBookIndexWeb.Components.MyComponents do defmacro __using__(_) do quote do import MyComponents.BookCard, only: [book_card: 1] + import MyComponents.BookSearch, only: [book_search: 1] import MyComponents.AuthorCard, only: [author_card: 1] import MyComponents.AuthorSearch, only: [author_search: 1] diff --git a/lib/decentralised_book_index_web/components/my_components/book_search.ex b/lib/decentralised_book_index_web/components/my_components/book_search.ex new file mode 100644 index 0000000..122e250 --- /dev/null +++ b/lib/decentralised_book_index_web/components/my_components/book_search.ex @@ -0,0 +1,95 @@ +defmodule DecentralisedBookIndexWeb.Components.MyComponents.BookSearch do + use Phoenix.Component + use DecentralisedBookIndexWeb, :verified_routes + + attr :search_query, :string, default: "" + attr :search_mode, :string, default: "title" + attr :search_mode_options, :list, required: true + attr :select_options, :list, required: true + attr :selected_option, :string, required: true + + def book_search(assigns) do + ~H""" +
+
+
+
+ +
+
+ +
+ +
+
+
+
+ <.link patch={~p"/books/new"}> + + + <.dropdown_settings + search_mode={@search_mode} + search_mode_options={@search_mode_options} + select_options={@select_options} + selected_option={@selected_option} + /> +
+
+
+ """ + end + + attr :search_mode, :string, default: "title" + attr :search_mode_options, :list, required: true + attr :select_options, :list, required: true + attr :selected_option, :string, required: true + + def dropdown_settings(assigns) do + ~H""" +
+ + + +
+ """ + end +end diff --git a/lib/decentralised_book_index_web/live/book_live/index.ex b/lib/decentralised_book_index_web/live/book_live/index.ex index 8fcb5ed..d5ae9ff 100644 --- a/lib/decentralised_book_index_web/live/book_live/index.ex +++ b/lib/decentralised_book_index_web/live/book_live/index.ex @@ -15,6 +15,14 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do + <.book_search + search_query={@search_query} + search_mode={@search_mode} + search_mode_options={@search_mode_options} + select_options={@select_options} + selected_option={@sort_by} + /> + <.table id="books" rows={@streams.books} @@ -94,7 +102,8 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do @impl true def mount(params, _session, socket) do search_query = Map.get(params, "query", "") - sort_by = Map.get(params, "sort_by", "name") |> validate_sort_by() + sort_by = Map.get(params, "sort_by", "title") |> validate_sort_by() + search_mode = Map.get(params, "search_mode", "title") |> validate_search_mode() page_params = AshPhoenix.LiveView.page_from_params(params, 10) page = Metadata.search_book!( @@ -111,6 +120,8 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do ) |> assign(:sort_by, sort_by) |> assign(:search_query, search_query) + |> assign(:search_mode, search_mode) + |> assign(:search_mode_options, search_mode_options()) |> assign(:select_options, sort_options()) |> assign(:page_params, page_params) |> assign(:page, page) @@ -176,4 +187,41 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do List.first(valid_keys) end end + + @impl true + def handle_event("change-sort", %{"sort_by" => sort_by}, socket) do + params = + socket.assigns.params + |> Map.put("sort_by", sort_by) + + {:noreply, push_patch(socket, to: ~p"/books?#{params}")} + end + + defp search_mode_options do + [ + {"Search by title", "title"}, + {"Search by isbn13", "isbn13"}, + {"Search by isbn", "isbn"}, + {"Search by asin", "asin"}, + ] + end + + def validate_search_mode(key) do + valid_keys = Enum.map(sort_options(), &elem(&1, 1)) + + if key in valid_keys do + key + else + List.first(valid_keys) + end + end + + @impl true + def handle_event("change-search-mode", %{"search_mode" => search_mode}, socket) do + params = + socket.assigns.params + |> Map.put("search_mode", search_mode) + + {:noreply, push_patch(socket, to: ~p"/books?#{params}")} + end end