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
- <%= 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") %> |
@@ -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"
})