Enable member creation functionality: implement MemberAddView, create MemberForm, update routes, templates, and add supporting styles.
This commit is contained in:
29
templates/backend/partials/messages.html
Normal file
29
templates/backend/partials/messages.html
Normal file
@@ -0,0 +1,29 @@
|
||||
{% if messages %}
|
||||
<div id="messages" class="flex flex-col p-2 m-4 -mt-4 gap-y-2" {% if request.htmx %} hx-swap-oob="true"{% endif %}>
|
||||
{% for message in messages %}
|
||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %}
|
||||
<div role="alert" class="alert alert-success">
|
||||
<i class="text-lg fa-solid fa-check"></i>
|
||||
<span>{{ message|safe }}</span>
|
||||
</div>
|
||||
{% elif message.level == DEFAULT_MESSAGE_LEVELS.WARNING %}
|
||||
<div role="alert" class="alert alert-warning">
|
||||
<i class="text-lg fa-solid fa-ban"></i>
|
||||
<span>{{ message|safe }}</span>
|
||||
</div>
|
||||
{% elif message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||
<div role="alert" class="alert alert-error">
|
||||
<i class="text-lg fa-solid fa-exclamation"></i>
|
||||
<span>{{ message|safe }}</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div role="alert" class="alert alert-info">
|
||||
<i class="text-lg fa-solid fa-info"></i>
|
||||
<span>{{ message|safe }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div id="messages"{% if request.htmx %} hx-swap-oob="true"{% endif %}></div>
|
||||
{% endif %}
|
||||
@@ -101,11 +101,15 @@
|
||||
|
||||
<!-- MAIN CONTENT-->
|
||||
<div class="drawer-content flex w-full">
|
||||
<main class="bg-base-100 border border-base-300 rounded-xl m-4 ml-2 p-6 w-full" id="content">
|
||||
{% block content %}
|
||||
<h1 class="text-3xl font-bold">Welcome!</h1>
|
||||
<p>This is your main content area.</p>
|
||||
{% endblock %}
|
||||
<main class="bg-base-100 border border-base-300 rounded-xl m-4 ml-2 p-6 w-full">
|
||||
{% include "backend/partials/messages.html" %}
|
||||
|
||||
<div id="content">
|
||||
{% block content %}
|
||||
<h1 class="text-3xl font-bold">Welcome!</h1>
|
||||
<p>This is your main content area.</p>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
{% endblocktranslate %}
|
||||
</div>
|
||||
|
||||
<form method="post">
|
||||
<form method="post" hx-post="{% url "backend:members:delete" object.pk %}" hx-target="#content">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="flex flex-row gap-2 mt-8">
|
||||
<a href="{% url "backend:members:list" %}" class="btn btn-neutral btn-outline grow lg:grow-0">{% translate "Cancel" %}</a>
|
||||
<a href="{% url "backend:members:list" %}" class="btn btn-neutral btn-outline grow lg:grow-0" hx-get="{% url "backend:members:list" %}" hx-target="#content">{% translate "Cancel" %}</a>
|
||||
<button type="submit" class="btn btn-error grow lg:grow-0"><i class="fa-solid fa-trash"></i>{% translate "Delete" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
|
||||
{% block content %}
|
||||
{% partialdef content inline %}
|
||||
{% if request.htmx %}
|
||||
{% include "backend/partials/messages.html" %}
|
||||
{% endif %}
|
||||
|
||||
<h1 class="page-title">{% translate "Members" %}</h1>
|
||||
|
||||
<div class="lg:hidden collapse collapse-plus bg-base-100 border-neutral border">
|
||||
@@ -59,7 +63,7 @@
|
||||
<i class="fa-solid fa-file-upload"></i>{% translate "Load members from file" %}
|
||||
</a>
|
||||
|
||||
<a class="btn btn-neutral btn-outline btn-sm grow" href="">
|
||||
<a class="btn btn-neutral btn-outline btn-sm grow" href="{% url "backend:members:add" %}" hx-get="{% url "backend:members:add" %}" hx-target="#content">
|
||||
<i class="fa-solid fa-plus"></i>{% translate "Add member" %}
|
||||
</a>
|
||||
</div>
|
||||
@@ -129,7 +133,7 @@
|
||||
<i class="fa-solid fa-eye"></i>{% translate "Details" %}
|
||||
</a>
|
||||
|
||||
<a class="btn btn-outline btn-error btn-sm" href="{% url "backend:members:delete" member.pk %}">
|
||||
<a class="btn btn-outline btn-error btn-sm" href="{% url "backend:members:delete" member.pk %}" hx-get="{% url "backend:members:delete" member.pk %}" hx-target="#content">
|
||||
<i class="fa-solid fa-trash"></i>{% translate "Delete" %}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
157
templates/members/member_form.html
Normal file
157
templates/members/member_form.html
Normal file
@@ -0,0 +1,157 @@
|
||||
{% extends "backend/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load form_field %}
|
||||
{% load avatar %}
|
||||
|
||||
{% block content %}
|
||||
{% partialdef content inline %}
|
||||
<h1 class="page-title">{% translate "Members" %}</h1>
|
||||
|
||||
<div class="flex flex-row gap-2 items-center lg:hidden">
|
||||
<div class="text-3xl min-w-12">
|
||||
<a href="{% url "backend:members:list" %}" hx-get="{% url "backend:members:list" %}" hx-target="#content">
|
||||
<i class="fa-solid fa-angle-left"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-2 grow justify-center items-center">
|
||||
{% if member %}
|
||||
<div class="font-bold text-xl">{{ member.user.get_full_name }}</div>
|
||||
|
||||
{% if member.user.is_superuser %}
|
||||
<div class="tooltip" data-tip="{% translate "This user is a site admin" %}">
|
||||
<div class="badge badge-sm badge-accent">
|
||||
<i class="fa-solid fa-user-shield"></i>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="font-bold text-xl">{% translate "Create new member" %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="flex min-w-12 justify-end">
|
||||
{% if member %}
|
||||
<a class="btn btn-error btn-outline" href="{% url "backend:members:delete" member.pk %}">
|
||||
<i class="fa-solid fa-trash"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if member %}
|
||||
<div class="mt-4 lg:hidden flex flex-row gap-2">
|
||||
<div class="mt-4 lg:hidden flex flex-row gap-2">
|
||||
{% if member.phone_number %}
|
||||
<a href="{{ member.phone_number.as_rfc3966 }}" class="btn btn-info btn-outline btn-sm grow">
|
||||
<i class="fa-solid fa-phone"></i>
|
||||
{{ member.phone }}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if member.emergency_phone_number %}
|
||||
<a href="{{ member.emergency_phone_number.as_rfc3966 }}" class="btn btn-error btn-outline btn-sm grow">
|
||||
<i class="fa-solid fa-file-medical"></i>
|
||||
{{ member.emergency_phone_number }}
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if config.TF_ENABLE_TEAMS %}
|
||||
<a href="?member__user__first_name={{ member.user.first_name }}&member__user__last_name={{ member.user.last_name }}" class="btn btn-sm w-full mt-2 btn-outline btn-neutral lg:hidden">
|
||||
<i class="fa-solid fa-ticket"></i>{% translate "View team memberships" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="flex flex-row items-center mt-8 gap-x-3 hidden lg:flex">
|
||||
{% avatar first_name=member.user.first_name last_name=member.user.last_name %}
|
||||
|
||||
<h2 class="page-subtitle border-b-0! mt-0!">{{ member.user.get_full_name }}</h2>
|
||||
|
||||
{% if member.user.is_superuser %}
|
||||
<div class="badge badge-accent"><i class="fa-solid fa-user-shield"></i>{% translate "Admin" %}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="justify-end hidden gap-2 lg:flex lg:flex-row grow">
|
||||
{% if member.phone %}
|
||||
<a href="{{ member.phone.as_rfc3966 }}" class="btn btn-outline btn-info"><i class="fa-solid fa-phone"></i>{{ member.phone }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if member.emergency_phone %}
|
||||
<a href="{{ member.emergency_phone.as_rfc3966 }}" class="btn btn-outline btn-error"><i class="fa-solid fa-file-medical"></i>{{ member.emergency_phone }}</a>
|
||||
{% endif %}
|
||||
|
||||
{% if config.TF_ENABLE_TEAMS %}
|
||||
<a href="?member__user__first_name={{ member.user.first_name }}&member__user__last_name={{ member.user.last_name }}" class="btn btn-outline btn-neutral">
|
||||
<i class="fa-solid fa-ticket"></i>{% translate "Team Memberships" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<a href="{% url "backend:members:members_delete" member.id %}" class="btn btn-error btn-outline">
|
||||
<i class="fa-solid fa-trash"></i>{% translate "Delete" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<h2 class="page-subtitle border-b-0! hidden lg:flex">{% translate "Create new member" %}</h2>
|
||||
{% endif %}
|
||||
|
||||
{% if form.errors %}
|
||||
<div class="flex flex-row items-center gap-2 p-2 m-4 rounded-lg bg-error">
|
||||
<i class="mr-2 text-3xl fa-solid fa-exclamation-triangle text-error-content"></i>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<div class="mb-1 font-semibold text-error-content">{% translate "Error" %}</div>
|
||||
<div class="text-sm text-error-content">{% translate "Please correct the errors below before saving again." %}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
<h2 class="page-subtitle">{% translate "Personal information" %}</h2>
|
||||
<div class="grid grid-cols-1 gap-4 mt-2 lg:grid-cols-2">
|
||||
{% form_field form.first_name %}
|
||||
{% form_field form.last_name %}
|
||||
{% form_field form.birthday %}
|
||||
</div>
|
||||
|
||||
<h2 class="page-subtitle">{% translate "Contact information" %}</h2>
|
||||
<div class="grid grid-cols-1 gap-4 mt-2 lg:grid-cols-2">
|
||||
{% form_field form.email %}
|
||||
{% form_field form.phone_number %}
|
||||
{% form_field form.emergency_phone_number %}
|
||||
</div>
|
||||
|
||||
<h2 class="page-subtitle">{% translate "Family information" %}</h2>
|
||||
<div class="grid grid-cols-1 gap-4 mt-2 lg:grid-cols-2">
|
||||
{% form_field form.family_members %}
|
||||
</div>
|
||||
|
||||
<h2 class="page-subtitle">{% translate "Club information" %}</h2>
|
||||
<div class="grid grid-cols-1 gap-4 mt-2 lg:grid-cols-2">
|
||||
{% form_field form.license %}
|
||||
{% form_field form.admin show_as_toggle=True %}
|
||||
</div>
|
||||
|
||||
<h2 class="page-subtitle">{% translate "Password" %}</h2>
|
||||
<div class="mt-2 text-sm text-justify">{% blocktranslate %}Setting the password here will overwrite the current password for this member, after changing the member will be prompted to set a new password at the next login.<br /><br />If both fields are empty the current password will not be changed.{% endblocktranslate %}</div>
|
||||
<div class="grid grid-cols-1 gap-4 mt-2 lg:grid-cols-2">
|
||||
{% form_field form.password %}
|
||||
{% form_field form.password_confirmation %}
|
||||
</div>
|
||||
|
||||
<button class="w-full mt-8 btn btn-neutral" type="submit">
|
||||
<i class="fa-solid fa-floppy-disk"></i>{% translate "Save" %}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript">
|
||||
new Choices(document.querySelector("#id_family_members"));
|
||||
</script>
|
||||
{% endpartialdef content %}
|
||||
{% endblock content %}
|
||||
Reference in New Issue
Block a user