feat: add membership fee status column to member list
- Add status column showing last completed or current cycle status - Add toggle to switch between last/current cycle view - Add color coding (green/red/gray) for paid/unpaid/suspended - Add filters for unpaid cycles in last/current cycle - Efficiently load cycles to avoid N+1 queries
This commit is contained in:
parent
06de9d2c8b
commit
99dc17bf4d
2 changed files with 240 additions and 35 deletions
|
|
@ -42,6 +42,66 @@
|
|||
paid_filter={@paid_filter}
|
||||
member_count={length(@members)}
|
||||
/>
|
||||
<div class="flex gap-2 items-center">
|
||||
<button
|
||||
type="button"
|
||||
phx-click="toggle_cycle_view"
|
||||
class={[
|
||||
"btn btn-sm",
|
||||
if(@show_current_cycle, do: "btn-primary", else: "btn-outline")
|
||||
]}
|
||||
aria-label={
|
||||
if(@show_current_cycle,
|
||||
do: gettext("Show last completed cycle"),
|
||||
else: gettext("Show current cycle")
|
||||
)
|
||||
}
|
||||
>
|
||||
<.icon name="hero-arrow-path" class="size-4" />
|
||||
{if(@show_current_cycle, do: gettext("Current Cycle"), else: gettext("Last Cycle"))}
|
||||
</button>
|
||||
<div class="dropdown">
|
||||
<label tabindex="0" class="btn btn-sm btn-outline">
|
||||
<.icon name="hero-funnel" class="size-4" />
|
||||
{gettext("Membership Fee")}
|
||||
</label>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow"
|
||||
>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="filter_unpaid_cycles"
|
||||
phx-value-filter="unpaid_last"
|
||||
class={if(@membership_fee_status_filter == :unpaid_last, do: "active", else: "")}
|
||||
>
|
||||
{gettext("Unpaid in last cycle")}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="filter_unpaid_cycles"
|
||||
phx-value-filter="unpaid_current"
|
||||
class={if(@membership_fee_status_filter == :unpaid_current, do: "active", else: "")}
|
||||
>
|
||||
{gettext("Unpaid in current cycle")}
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="filter_unpaid_cycles"
|
||||
phx-value-filter=""
|
||||
class={if(@membership_fee_status_filter == nil, do: "active", else: "")}
|
||||
>
|
||||
{gettext("All")}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<.live_component
|
||||
module={MvWeb.Components.FieldVisibilityDropdownComponent}
|
||||
id="field-visibility-dropdown"
|
||||
|
|
@ -255,6 +315,40 @@
|
|||
{if member.paid == true, do: gettext("Yes"), else: gettext("No")}
|
||||
</span>
|
||||
</:col>
|
||||
<:col
|
||||
:let={member}
|
||||
label={
|
||||
~H"""
|
||||
<div class="flex items-center gap-2">
|
||||
<span>{gettext("Membership Fee Status")}</span>
|
||||
<button
|
||||
type="button"
|
||||
phx-click="toggle_cycle_view"
|
||||
class="btn btn-xs btn-ghost"
|
||||
title={
|
||||
if(@show_current_cycle,
|
||||
do: gettext("Switch to last completed cycle"),
|
||||
else: gettext("Switch to current cycle")
|
||||
)
|
||||
}
|
||||
>
|
||||
<.icon name="hero-arrow-path" class="size-3" />
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
>
|
||||
<%= if badge = MvWeb.MemberLive.Index.MembershipFeeStatus.format_cycle_status_badge(
|
||||
MvWeb.MemberLive.Index.MembershipFeeStatus.get_cycle_status_for_member(member, @show_current_cycle)
|
||||
) do %>
|
||||
<span class={["badge", badge.color]}>
|
||||
<.icon name={badge.icon} class="size-4" />
|
||||
{badge.label}
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="badge badge-ghost">{gettext("No cycle")}</span>
|
||||
<% end %>
|
||||
</:col>
|
||||
<:action :let={member}>
|
||||
<div class="sr-only">
|
||||
<.link navigate={~p"/members/#{member}"}>{gettext("Show")}</.link>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue