{% extends "management/base.html" %} {% load lucide ui i18n static %} {% block heading %}{{ member.get_full_name }}{% endblock heading %} {% block topbar_context %} {% if member.contact_email %}{{ member.contact_email }}{% endif %} {% if current_membership %} {{ current_membership.get_status_display }} {% endif %} {% endblock topbar_context %} {% block actions %} {% if is_club_admin %} {% lucide "pencil" size=16 %} {% trans "Edit" %} {% endif %} {% endblock actions %} {% block panel %}

{% lucide "user" size=18 %} {% trans "Personal information" %}

{% trans "Date of birth" %}
{{ member.date_of_birth|default:"—" }}
{% trans "Phone" %}
{{ member.phone.as_international|default:"—" }}
{% trans "Emergency phone" %}
{{ member.emergency_phone.as_international|default:"—" }}
{% for guardian in guardians %}
{% trans "Parent phone" %} — {{ guardian.get_full_name }}
{{ guardian.phone.as_international|default:"—" }}
{% trans "Parent emergency phone" %} — {{ guardian.get_full_name }}
{{ guardian.emergency_phone.as_international|default:"—" }}
{% endfor %}
{% if member.phone %} {% lucide "phone" size=14 %} {% trans "Call" %} {% endif %} {% if member.emergency_phone %} {% lucide "shield-alert" size=14 %} {% trans "Emergency call" %} {% endif %}
{% if guardians %}
{% lucide "users" size=12 %} {% trans "Parent/guardian contact" %}
{% for guardian in guardians %} {% if guardian.phone or guardian.emergency_phone %} {% endif %} {% endfor %} {% endif %}
{% comment %} A Member has no club of its own -- ClubMembership is the only thing that actually ties this person to *this* club, so it gets its own panel: the current season's standing, plus every season they've been part of. {% endcomment %}

{% lucide "id-card" size=18 %} {% trans "Club membership" %}

{% if current_membership %} {% if current_membership.is_guardian %} {% comment %} Stated plainly rather than left to be inferred from an empty fee: a guardian is deliberately missing from the member list and every member count, and someone looking at this page needs to know that is on purpose. See club.models.ClubMembership.Kind. {% endcomment %}
{% lucide "users" size=16 %} {% trans "Guardian: attached to the club as a parent of a member. Holds the login, owes no fee, and is not counted as a member." %}
{% endif %}
{% trans "Joined as" %}
{{ current_membership.get_kind_display|capfirst }}
{% trans "License" %}
{{ current_membership.license|default:"—" }}
{% trans "Status" %}
{{ current_membership.get_status_display }}
{% if not current_membership.is_guardian %}
{% trans "Fee status" %}
{{ current_membership.get_fee_status_display }}
{% endif %}
{% else %}

{% trans "Not rostered for the current season." %}

{% endif %} {% if membership_history %}

{% trans "Season history" %}

{% for membership in membership_history %} {% endfor %}
{% trans "Season" %} {% trans "Status" %} {% trans "Fee status" %} {% trans "License" %}
{{ membership.season.start_date|date:"Y" }} - {{ membership.season.end_date|date:"Y" }} {{ membership.get_status_display }} {{ membership.get_fee_status_display }} {{ membership.license|default:"—" }}
{% endif %}
{# Attendance, Documents and Referee eligibility side by side rather than three full-width rows -- h-full keeps them matched in height regardless of which has more content. #}
{% if show_attendance %} {# D7's season card: a 12-bar attendance sparkline (present/absent/upcoming, oldest first) beside the season's Present/Absent/No-reply totals. #}

{% lucide "calendar-check" size=18 %} {% trans "Attendance" %}

{% if not attendance_sparkline %}

{% trans "No events yet this season." %}

{% else %}
{% for bar in attendance_sparkline %} {% endfor %}
{{ attendance_counts.present }}
{% trans "Present" %}
{{ attendance_counts.absent }}
{% trans "Absent" %}
{{ attendance_counts.no_reply }}
{% trans "No reply" %}
{{ attendance_counts.no_shows }}
{% trans "No-shows" %}
{% endif %}
{% endif %} {% comment %} Onboarding checklist -- club.services.onboarding.checklist_for, paired with MemberRequirementStatus if one exists. Any staff can see it (same visibility as the rest of this page), but only an admin/MEMBER_ADMIN can mark an item done or reopen it (MemberAdminRequiredMixin on the three requirement views in management/views.py) -- see the module docstring on club/services/onboarding.py for why this stays separate from ClubMembership.status/fee_status. {% endcomment %}

{% lucide "clipboard-check" size=18 %} {% trans "Documents" %}

{% if not current_membership %}

{% trans "Not rostered for the current season -- nothing to check off yet." %}

{% elif not checklist %}

{% trans "This club has no onboarding requirements set up." %}

{% else %}
{% for requirement, status in checklist %}
{{ requirement.name }} {% if status.is_complete %} {% trans "Complete" %} {% elif status %} {% trans "Incomplete" %} {% else %} {% trans "Not started" %} {% endif %}
{% if requirement.description %}

{{ requirement.description }}

{% endif %} {% if status.is_complete %}

{% blocktrans with who=status.completed_by when=status.completed_at|date:"j M Y H:i" %}Completed by {{ who }} on {{ when }}{% endblocktrans %}

{% endif %} {% if status.note %}

“{{ status.note }}”

{% endif %} {% if status.document %} {% lucide "download" size=13 %} {% trans "Download document" %} {% endif %}
{% if can_manage_members %}
{% if status.is_complete %}
{% csrf_token %}
{% else %} {% endif %}
{% endif %}
{% endfor %}
{% endif %}
{% if referee_profile or is_club_admin %}

{% lucide "flag" size=18 %} {% trans "Referee eligibility" %}

{% if is_club_admin %} {% endif %}
{% if referee_profile and referee_profile.level %}
{% trans "Level" %}
{{ referee_profile.level }}
{% trans "Valid until" %}
{{ referee_profile.valid_until|default:"—" }} {% if referee_profile.is_currently_valid %} {% trans "Valid" %} {% elif referee_profile.valid_until %} {% trans "Expired" %} {% else %} {% trans "No validity set" %} {% endif %}
{% if referee_profile.is_eligible %}
{% trans "Can referee for" %}
{% for team in referee_profile.eligible_teams %} {{ team.name }} {% empty %} {% trans "This level has no teams linked yet." %} {% endfor %}
{% else %}
{% lucide "triangle-alert" size=16 %} {% trans "Not currently eligible to referee -- set or extend the validity date above to reinstate them." %}
{% endif %} {% else %}

{% trans "Not eligible to referee for any team." %}

{% endif %}
{% endif %}
{% if is_club_admin %} {% url 'management:member_referee_eligibility_update' member.pk as referee_eligibility_url %} {% trans "Referee eligibility" as referee_eligibility_title %} {% trans "Save" as save_label %} {% include "controlpanel/_modal_form.html" with modal_id="referee_eligibility_modal" title=referee_eligibility_title form=referee_eligibility_form action_url=referee_eligibility_url submit_label=save_label submit_icon="save" %} {% endif %} {% trans "Add parent" as add_parent_label %} {% trans "Add child" as add_child_label %} {% trans "If this email has no account yet, one is created and they set a password via the reset link." as add_parent_blurb %} {% blocktrans with short_name=member.get_short_name asvar remove_from_family_label %}Remove {{ short_name }} from family{% endblocktrans %} {% trans "Remove from family" as remove_from_family_title %} {% trans "Remove" as remove_label %} {% for family_group in family_groups %}

{% lucide "users" size=18 %} {{ family_group.family }}

{% if is_club_admin %}
{% endif %}
{% include "management/_family_members_table.html" with group=family_group next_url=request.path %}
{% if is_club_admin %} {% url 'management:family_add_parent' family_group.family.pk as add_parent_url %} {% url 'management:family_add_child' family_group.family.pk as add_child_url %} {% url 'management:member_detach_family' member.pk family_group.family.pk as detach_family_url %} {% blocktrans with full_name=member.get_full_name family_name=family_group.family asvar detach_family_body %}Remove {{ full_name }} from {{ family_name }}? They become a standalone member -- nothing else about them changes.{% endblocktrans %} {% include "controlpanel/_modal_form.html" with modal_id=family_group.family.pk|dom_id:"add_parent_modal" title=add_parent_label form=add_parent_form action_url=add_parent_url submit_label=add_parent_label submit_icon="user-plus" blurb=add_parent_blurb %} {% include "controlpanel/_modal_form.html" with modal_id=family_group.family.pk|dom_id:"add_child_modal" title=add_child_label form=add_child_form action_url=add_child_url submit_label=add_child_label submit_icon="baby" %} {% include "controlpanel/_confirm_modal.html" with modal_id=family_group.family.pk|dom_id:"detach_family_modal" title=remove_from_family_title body=detach_family_body action_url=detach_family_url submit_label=remove_label submit_icon="user-x" %} {% endif %} {% endfor %} {% if is_club_admin %}

{% lucide "users" size=18 %} {% trans "Family" %}

{% if not family_groups %}

{% trans "Not part of a family." %}

{% endif %}
{% url 'management:member_attach_family' member.pk as attach_family_url %} {% trans "Add to family" as add_to_family_title %} {% trans "Add" as add_label %} {% trans "Pick an existing family, or leave it blank to start a new one." as attach_family_blurb %} {% include "controlpanel/_modal_form.html" with modal_id="attach_family_modal" title=add_to_family_title form=attach_to_family_form action_url=attach_family_url submit_label=add_label submit_icon="user-plus" blurb=attach_family_blurb %} {% endif %} {% if can_manage_members %} {% for requirement, status in checklist %} {% if not status.is_complete %} {% endif %} {% endfor %} {% endif %} {% endblock panel %} {% block extra_body %} {% endblock extra_body %}