102 lines
4.8 KiB
Python
102 lines
4.8 KiB
Python
"""
|
|
Member-related CLI commands.
|
|
"""
|
|
|
|
import argparse
|
|
from typing import TYPE_CHECKING
|
|
|
|
if TYPE_CHECKING:
|
|
from backend.cli.base import NimbusFlowCLI
|
|
|
|
from backend.cli.utils import format_member_row, create_table_header, create_table_separator, TableColors
|
|
|
|
|
|
def cmd_members_list(cli: "NimbusFlowCLI", args) -> None:
|
|
"""List all members with optional filters."""
|
|
# Get all classifications for lookup
|
|
classifications = cli.classification_repo.list_all()
|
|
classification_map = {c.ClassificationId: c.ClassificationName for c in classifications}
|
|
|
|
# Apply filters
|
|
if args.classification:
|
|
# Find classification ID by name
|
|
classification_id = None
|
|
for c in classifications:
|
|
if c.ClassificationName.lower() == args.classification.lower():
|
|
classification_id = c.ClassificationId
|
|
break
|
|
|
|
if classification_id is None:
|
|
print(f"{TableColors.ERROR}Classification '{args.classification}' not found{TableColors.RESET}")
|
|
return
|
|
|
|
members = cli.member_repo.get_by_classification_ids([classification_id])
|
|
elif args.active:
|
|
members = cli.member_repo.get_active()
|
|
else:
|
|
members = cli.member_repo.list_all()
|
|
|
|
if not members:
|
|
print(f"{TableColors.DIM}No members found.{TableColors.RESET}")
|
|
return
|
|
|
|
# Print styled header
|
|
print()
|
|
print(create_table_header("ID ", "First Name ", "Last Name ", "Classification ", "Status ", "Email"))
|
|
print(create_table_separator(90))
|
|
|
|
# Print members
|
|
for member in members:
|
|
classification_name = classification_map.get(member.ClassificationId)
|
|
print(format_member_row(member, classification_name))
|
|
|
|
print()
|
|
print(f"{TableColors.SUCCESS}Total: {len(members)} members{TableColors.RESET}")
|
|
|
|
|
|
def cmd_members_show(cli: "NimbusFlowCLI", args) -> None:
|
|
"""Show detailed information about a specific member."""
|
|
member = cli.member_repo.get_by_id(args.member_id)
|
|
if not member:
|
|
print(f"{TableColors.ERROR}Member with ID {args.member_id} not found{TableColors.RESET}")
|
|
return
|
|
|
|
# Get classification name
|
|
classification = None
|
|
if member.ClassificationId:
|
|
classification = cli.classification_repo.get_by_id(member.ClassificationId)
|
|
|
|
print(f"\n{TableColors.HEADER}Member Details (ID: {member.MemberId}){TableColors.RESET}")
|
|
print(f"{TableColors.BORDER}{'─' * 50}{TableColors.RESET}")
|
|
print(f"{TableColors.BOLD}Name:{TableColors.RESET} {member.FirstName} {member.LastName}")
|
|
print(f"{TableColors.BOLD}Email:{TableColors.RESET} {member.Email or f'{TableColors.DIM}N/A{TableColors.RESET}'}")
|
|
print(f"{TableColors.BOLD}Phone:{TableColors.RESET} {member.PhoneNumber or f'{TableColors.DIM}N/A{TableColors.RESET}'}")
|
|
print(f"{TableColors.BOLD}Classification:{TableColors.RESET} {TableColors.YELLOW}{classification.ClassificationName if classification else f'{TableColors.DIM}N/A'}{TableColors.RESET}")
|
|
|
|
active_status = f"{TableColors.SUCCESS}Yes{TableColors.RESET}" if member.IsActive else f"{TableColors.ERROR}No{TableColors.RESET}"
|
|
print(f"{TableColors.BOLD}Active:{TableColors.RESET} {active_status}")
|
|
print(f"{TableColors.BOLD}Notes:{TableColors.RESET} {member.Notes or f'{TableColors.DIM}N/A{TableColors.RESET}'}")
|
|
|
|
print(f"\n{TableColors.HEADER}Schedule History:{TableColors.RESET}")
|
|
print(f"{TableColors.BOLD}Last Scheduled:{TableColors.RESET} {member.LastScheduledAt or f'{TableColors.DIM}Never{TableColors.RESET}'}")
|
|
print(f"{TableColors.BOLD}Last Accepted:{TableColors.RESET} {member.LastAcceptedAt or f'{TableColors.DIM}Never{TableColors.RESET}'}")
|
|
print(f"{TableColors.BOLD}Last Declined:{TableColors.RESET} {member.LastDeclinedAt or f'{TableColors.DIM}Never{TableColors.RESET}'}")
|
|
|
|
decline_color = TableColors.ERROR if member.DeclineStreak > 0 else TableColors.SUCCESS
|
|
print(f"{TableColors.BOLD}Decline Streak:{TableColors.RESET} {decline_color}{member.DeclineStreak}{TableColors.RESET}")
|
|
|
|
|
|
def setup_members_parser(subparsers) -> None:
|
|
"""Set up member-related command parsers."""
|
|
# Members commands
|
|
members_parser = subparsers.add_parser("members", help="Manage members")
|
|
members_subparsers = members_parser.add_subparsers(dest="members_action", help="Members actions")
|
|
|
|
# members list
|
|
members_list_parser = members_subparsers.add_parser("list", help="List members")
|
|
members_list_parser.add_argument("--active", action="store_true", help="Show only active members")
|
|
members_list_parser.add_argument("--classification", type=str, help="Filter by classification name")
|
|
|
|
# members show
|
|
members_show_parser = members_subparsers.add_parser("show", help="Show member details")
|
|
members_show_parser.add_argument("member_id", type=int, help="Member ID to show") |