Large uncommitted body of work accumulated across sessions on this branch -- committing as a checkpoint so it's tracked and future worktree-isolated agents see the real codebase instead of a stale ancestor commit. Covers the management app's dedicated Tailwind theme and templates, the club onboarding requirement/signup workflow (club/services/onboarding.py, requirement/status models, sign-up dashboard), fee/status auto-activation decoupling, referee management, and the new events calendar grid service layer. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
87 lines
4.3 KiB
HTML
87 lines
4.3 KiB
HTML
{% extends "management/base.html" %}
|
|
{% load lucide i18n %}
|
|
|
|
{% block heading %}{% trans "Review import" %}{% endblock heading %}
|
|
|
|
{% block panel %}
|
|
{% if not season %}
|
|
<div class="alert alert-warning mb-4">
|
|
{% lucide "triangle-alert" size=16 %}
|
|
<span>{% trans "No active season — members will still be created, but won't be rostered for one until it exists." %}</span>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="card card-body">
|
|
<p class="text-sm text-muted">
|
|
{% blocktrans count counter=valid_count %}{{ counter }} member will be created.{% plural %}{{ counter }} members will be created.{% endblocktrans %}
|
|
{% if skipped_count %}{% blocktrans count counter=skipped_count %}{{ counter }} row will be skipped.{% plural %}{{ counter }} rows will be skipped.{% endblocktrans %}{% endif %}
|
|
</p>
|
|
|
|
<table class="table">
|
|
<thead>
|
|
<tr>
|
|
<th>{% trans "Row" %}</th>
|
|
<th>{% trans "Last name" %}</th>
|
|
<th>{% trans "First name" %}</th>
|
|
<th>{% trans "Email" %}</th>
|
|
<th>{% trans "Family" %}</th>
|
|
<th>{% trans "Joining as" %}</th>
|
|
<th>{% trans "Outcome" %}</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for result in results %}
|
|
<tr>
|
|
<td class="font-mono text-xs">{{ result.line_number }}</td>
|
|
<td>{{ result.raw.last_name }}</td>
|
|
<td>{{ result.raw.first_name }}</td>
|
|
<td class="text-muted">{{ result.raw.email }}</td>
|
|
<td>
|
|
{% if result.family_group %}
|
|
{{ result.family_group }}
|
|
{% if result.family_role %}<span class="badge badge-neutral badge-sm">{{ result.family_role|capfirst }}</span>{% endif %}
|
|
{% else %}
|
|
<span class="text-dim">—</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% comment %}
|
|
A guardian holds the login for a child but is not a member:
|
|
no fee, and not counted in any member total. See
|
|
club.models.ClubMembership.Kind.
|
|
{% endcomment %}
|
|
{% if result.membership_kwargs.kind == "guardian" %}
|
|
<span class="badge badge-warning badge-sm">{% trans "Guardian" %}</span>
|
|
{% else %}
|
|
<span class="badge badge-neutral badge-sm">{% trans "Member" %}</span>
|
|
{% endif %}
|
|
</td>
|
|
<td>
|
|
{% if result.member %}
|
|
<span class="badge badge-success badge-sm">{% trans "Will create" %}</span>
|
|
{% else %}
|
|
<span class="badge badge-error badge-sm">{% trans "Skipped" %}</span>
|
|
<div class="mt-1 text-xs text-muted">{{ result.errors|join:"; " }}</div>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
{% empty %}
|
|
<tr>
|
|
<td colspan="7" class="py-6 text-center text-muted">{% trans "No rows found in the uploaded file." %}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<div class="mt-2 flex items-center gap-2 pt-2">
|
|
<a class="btn btn-outline gap-2" href="{% url 'management:member_import' %}">{% lucide "arrow-left" size=16 %} {% trans "Back" %}</a>
|
|
{% if valid_count %}
|
|
<form method="post" action="{% url 'management:member_import_confirm' %}">
|
|
{% csrf_token %}
|
|
<button class="btn btn-primary gap-2" type="submit">{% lucide "check" size=16 %} {% blocktrans %}Confirm import ({{ valid_count }}){% endblocktrans %}</button>
|
|
</form>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock panel %}
|