diff --git a/lib/food_order/products.ex b/lib/food_order/products.ex index 843b7e7..d120847 100644 --- a/lib/food_order/products.ex +++ b/lib/food_order/products.ex @@ -26,6 +26,9 @@ defmodule FoodOrder.Products do {:name, name}, query -> name = "%#{name}%" where(query, [q], ilike(q.name, ^name)) + + {:sort, %{sort_by: sort_by, sort_order: sort_order}}, query -> + order_by(query, [q], [{^sort_order, ^sort_by}]) end) |> Repo.all() end diff --git a/lib/food_order_web/components/core_components.ex b/lib/food_order_web/components/core_components.ex index 1594532..f08d4ab 100644 --- a/lib/food_order_web/components/core_components.ex +++ b/lib/food_order_web/components/core_components.ex @@ -471,6 +471,8 @@ defmodule FoodOrderWeb.CoreComponents do slot :col, required: true do attr :label, :string + attr :link, :any + attr :options, :map end slot :action, doc: "the slot for showing user actions in the last table column" @@ -486,7 +488,24 @@ defmodule FoodOrderWeb.CoreComponents do - + @@ -529,6 +548,29 @@ defmodule FoodOrderWeb.CoreComponents do """ end + defp is_active(col) do + if Atom.to_string(col[:options][:sort_by]) == String.downcase(col[:label]) do + "text-fuchsia-500" + else + "text-gray-500" + end + end + + defp create_sort_link(link, options, label) do + sort_order = (options[:sort_order] == :desc && :asc) || :desc + + params = + options + |> Map.put(:sort_by, String.downcase(label)) + |> Map.put(:sort_order, sort_order) + |> Map.to_list() + |> Enum.reduce("", fn {k, v}, acc -> + acc <> "#{Atom.to_string(k)}=#{v}&" + end) + + "#{link}?#{params}" + end + @doc """ Renders a data list. diff --git a/lib/food_order_web/live/admin/product_live/index/index.ex b/lib/food_order_web/live/admin/product_live/index/index.ex index 9a94427..1fb447b 100644 --- a/lib/food_order_web/live/admin/product_live/index/index.ex +++ b/lib/food_order_web/live/admin/product_live/index/index.ex @@ -6,8 +6,12 @@ defmodule FoodOrderWeb.Admin.ProductLive.Index do def handle_params(params, _uri, socket) do live_action = socket.assigns.live_action name = params["name"] || "" - products = Products.list_products(name: name) - assigns = [name: name, products: products, loading: false] + sort_by = (params["sort_by"] || "updated_at") |> String.to_atom() + sort_order = (params["sort_order"] || "desc") |> String.to_atom() + sort = %{sort_by: sort_by, sort_order: sort_order} + products = Products.list_products(name: name, sort: sort) + options = Map.merge(sort, %{name: name}) + assigns = [options: options, products: products, loading: false] socket = socket @@ -51,7 +55,10 @@ defmodule FoodOrderWeb.Admin.ProductLive.Index do defp apply_filters(socket, name) do assings = [products: [], name: name, loading: true] send(self(), {:list_product, name}) - assign(socket, assings) + + socket + |> assign(assings) + |> update(:options, &Map.put(&1, :name, name)) end defp perform_filter(socket, params) do @@ -61,11 +68,15 @@ defmodule FoodOrderWeb.Admin.ProductLive.Index do end defp return_response([], socket, params) do - assigns = [loading: false, products: [], name: params[:name]] + assigns = [ + loading: false, + products: [] + ] socket - |> put_flash(:error, "No products found for #{params[:name]}") |> assign(assigns) + |> update(:options, &Map.put(&1, :name, params[:name])) + |> put_flash(:error, "No products found for #{params[:name]}") end defp return_response(products, socket, _params) do diff --git a/lib/food_order_web/live/admin/product_live/index/index.html.heex b/lib/food_order_web/live/admin/product_live/index/index.html.heex index ae57e76..4037e76 100644 --- a/lib/food_order_web/live/admin/product_live/index/index.html.heex +++ b/lib/food_order_web/live/admin/product_live/index/index.html.heex @@ -2,7 +2,7 @@ List Products <:actions>
- <.search_by_product name={@name} /> + <.search_by_product name={@options.name} /> <.link patch={~p"/admin/products/new"} class="text-[0.8125rem] text-zinc-900 font-semibold hover:text-zinc-700">New Product
@@ -16,7 +16,7 @@ <% else %> <.table id="products" rows={@products} row_click={&JS.navigate(~p"/admin/products/#{&1}")}> - <:col :let={product} label="Name" ><%= product.name %> + <:col :let={product} label="Name" options={@options} link={~p"/admin/products"}><%= product.name %> <:col :let={product} label="Price" ><%= product.price %> <:col :let={product} label="Size" ><%= product.size %> diff --git a/priv/repo/seeds.exs b/priv/repo/seeds.exs index 0dcb86b..4ffca0b 100644 --- a/priv/repo/seeds.exs +++ b/priv/repo/seeds.exs @@ -12,13 +12,13 @@ for _ <- 0..50, }) Accounts.register_user(%{ - email: "admin@elxpro.com", - password: "Admin@elxpro123", + email: "admin@food.com", + password: "Admin@food123", role: "ADMIN" }) Accounts.register_user(%{ - email: "user@elxpro.com", - password: "User@elxpro123", + email: "user@food.com", + password: "User@food123", role: "USER" })
<%= col[:label] %> + <%= if col[:link] do %> + <.link patch={create_sort_link(col[:link], col[:options], col[:label])} > +
+ + <%= col[:label] %> + + <%= if col[:options][:sort_order] == :asc do %> + + <% else %> + + <% end %> +
+ + <% else %> + <%= col[:label] %> + <% end %> +
<%= gettext("Actions") %>