From 7a4d30ba5eb327274315b47c4692a588a2ac2841 Mon Sep 17 00:00:00 2001 From: KKlochko Date: Sun, 30 Mar 2025 15:57:50 +0300 Subject: [PATCH] Add the BookCard component to the Book Index LiveView. --- .../live/book_live/index.ex | 77 +++++++++++++++++-- 1 file changed, 69 insertions(+), 8 deletions(-) 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 6e41a1e..8fcb5ed 100644 --- a/lib/decentralised_book_index_web/live/book_live/index.ex +++ b/lib/decentralised_book_index_web/live/book_live/index.ex @@ -1,6 +1,8 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do use DecentralisedBookIndexWeb, :live_view + alias DecentralisedBookIndex.Metadata + @impl true def render(assigns) do ~H""" @@ -52,6 +54,29 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do + <%= if Enum.empty?(@page.results) do %> +
+
+

+ No Books +

+
+
+ <% else %> +
+ <%= for book <- @page.results do %> + <.book_card book={book} /> + <% end %> +
+ + <.pagination + endpoint={~p"/books"} + page={@page} + page_params={@page_params} + params={@params} + /> + <% end %> + <.modal :if={@live_action in [:new, :edit]} id="book-modal" show on_cancel={JS.patch(~p"/books")}> <.live_component module={DecentralisedBookIndexWeb.BookLive.FormComponent} @@ -67,14 +92,32 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do end @impl true - def mount(_params, _session, socket) do - {:ok, - socket - |> stream( - :books, - Ash.read!(DecentralisedBookIndex.Metadata.Book, actor: socket.assigns[:current_user]) - ) - |> assign_new(:current_user, fn -> nil end)} + def mount(params, _session, socket) do + search_query = Map.get(params, "query", "") + sort_by = Map.get(params, "sort_by", "name") |> validate_sort_by() + page_params = AshPhoenix.LiveView.page_from_params(params, 10) + + page = Metadata.search_book!( + search_query, + page: page_params ++ [count: true], + actor: socket.assigns[:current_user] + ) + + socket = + socket + |> stream( + :books, + Ash.read!(DecentralisedBookIndex.Metadata.Book, actor: socket.assigns[:current_user]) + ) + |> assign(:sort_by, sort_by) + |> assign(:search_query, search_query) + |> assign(:select_options, sort_options()) + |> assign(:page_params, page_params) + |> assign(:page, page) + |> assign(:params, params) + |> assign_new(:current_user, fn -> nil end) + + {:ok, socket} end @impl true @@ -115,4 +158,22 @@ defmodule DecentralisedBookIndexWeb.BookLive.Index do {:noreply, stream_delete(socket, :books, book)} end + + defp sort_options do + [ + {"Sort by title", "title"}, + {"Sort by recently updated", "-updated_at"}, + {"Sort by recently added", "-inserted_at"}, + ] + end + + def validate_sort_by(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 end