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 %>
+
+ <% 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