Refactor filters to use cycle status instead of paid field
Replace paid_filter with cycle_status_filter that filters based on membership fee cycle status (last or current cycle). Update PaymentFilterComponent to use new filter with options All, Paid, Unpaid. Remove membership fee status filter dropdown. Extend filter_members_by_cycle_status/3 to support both paid and unpaid filtering. Update toggle_cycle_view to preserve filter state in URL.
This commit is contained in:
parent
098b3b0a2a
commit
c65b3808bf
10 changed files with 490 additions and 247 deletions
|
|
@ -2,11 +2,12 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
@moduledoc """
|
||||
Provides the PaymentFilter Live-Component.
|
||||
|
||||
A dropdown filter for filtering members by payment status (paid/not paid/all).
|
||||
A dropdown filter for filtering members by cycle payment status (paid/unpaid/all).
|
||||
Uses DaisyUI dropdown styling and sends filter changes to parent LiveView.
|
||||
Filter is based on cycle status (last or current cycle, depending on cycle view toggle).
|
||||
|
||||
## Props
|
||||
- `:paid_filter` - Current filter state: `nil` (all), `:paid`, or `:not_paid`
|
||||
- `:cycle_status_filter` - Current filter state: `nil` (all), `:paid`, or `:unpaid`
|
||||
- `:id` - Component ID (required)
|
||||
- `:member_count` - Number of filtered members to display in badge (optional, default: 0)
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
socket =
|
||||
socket
|
||||
|> assign(:id, assigns.id)
|
||||
|> assign(:paid_filter, assigns[:paid_filter])
|
||||
|> assign(:cycle_status_filter, assigns[:cycle_status_filter])
|
||||
|> assign(:member_count, assigns[:member_count] || 0)
|
||||
|
||||
{:ok, socket}
|
||||
|
|
@ -45,7 +46,7 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
type="button"
|
||||
class={[
|
||||
"btn gap-2",
|
||||
@paid_filter && "btn-active"
|
||||
@cycle_status_filter && "btn-active"
|
||||
]}
|
||||
phx-click="toggle_dropdown"
|
||||
phx-target={@myself}
|
||||
|
|
@ -54,8 +55,8 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
aria-label={gettext("Filter by payment status")}
|
||||
>
|
||||
<.icon name="hero-funnel" class="h-5 w-5" />
|
||||
<span class="hidden sm:inline">{filter_label(@paid_filter)}</span>
|
||||
<span :if={@paid_filter} class="badge badge-primary badge-sm">{@member_count}</span>
|
||||
<span class="hidden sm:inline">{filter_label(@cycle_status_filter)}</span>
|
||||
<span :if={@cycle_status_filter} class="badge badge-primary badge-sm">{@member_count}</span>
|
||||
</button>
|
||||
|
||||
<ul
|
||||
|
|
@ -70,22 +71,22 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
<button
|
||||
type="button"
|
||||
role="menuitemradio"
|
||||
aria-checked={to_string(@paid_filter == nil)}
|
||||
class={@paid_filter == nil && "active"}
|
||||
aria-checked={to_string(@cycle_status_filter == nil)}
|
||||
class={@cycle_status_filter == nil && "active"}
|
||||
phx-click="select_filter"
|
||||
phx-value-filter=""
|
||||
phx-target={@myself}
|
||||
>
|
||||
<.icon name="hero-users" class="h-4 w-4" />
|
||||
{gettext("All payment statuses")}
|
||||
{gettext("All")}
|
||||
</button>
|
||||
</li>
|
||||
<li role="none">
|
||||
<button
|
||||
type="button"
|
||||
role="menuitemradio"
|
||||
aria-checked={to_string(@paid_filter == :paid)}
|
||||
class={@paid_filter == :paid && "active"}
|
||||
aria-checked={to_string(@cycle_status_filter == :paid)}
|
||||
class={@cycle_status_filter == :paid && "active"}
|
||||
phx-click="select_filter"
|
||||
phx-value-filter="paid"
|
||||
phx-target={@myself}
|
||||
|
|
@ -98,14 +99,14 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
<button
|
||||
type="button"
|
||||
role="menuitemradio"
|
||||
aria-checked={to_string(@paid_filter == :not_paid)}
|
||||
class={@paid_filter == :not_paid && "active"}
|
||||
aria-checked={to_string(@cycle_status_filter == :unpaid)}
|
||||
class={@cycle_status_filter == :unpaid && "active"}
|
||||
phx-click="select_filter"
|
||||
phx-value-filter="not_paid"
|
||||
phx-value-filter="unpaid"
|
||||
phx-target={@myself}
|
||||
>
|
||||
<.icon name="hero-x-circle" class="h-4 w-4 text-error" />
|
||||
{gettext("Not paid")}
|
||||
{gettext("Unpaid")}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -136,11 +137,11 @@ defmodule MvWeb.Components.PaymentFilterComponent do
|
|||
|
||||
# Parse filter string to atom
|
||||
defp parse_filter("paid"), do: :paid
|
||||
defp parse_filter("not_paid"), do: :not_paid
|
||||
defp parse_filter("unpaid"), do: :unpaid
|
||||
defp parse_filter(_), do: nil
|
||||
|
||||
# Get display label for current filter
|
||||
defp filter_label(nil), do: gettext("All payment statuses")
|
||||
defp filter_label(nil), do: gettext("All")
|
||||
defp filter_label(:paid), do: gettext("Paid")
|
||||
defp filter_label(:not_paid), do: gettext("Not paid")
|
||||
defp filter_label(:unpaid), do: gettext("Unpaid")
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue