1
0
mirror of https://gitlab.crans.org/bde/nk20 synced 2024-11-26 18:37:12 +00:00

Merge branch 'front_club' into 'master'

Front club

See merge request bde/nk20!68
This commit is contained in:
Pierre-antoine Comby 2020-03-25 17:02:55 +01:00
commit c41999422f
17 changed files with 380 additions and 261 deletions

View File

@ -5,7 +5,7 @@
"fields": { "fields": {
"name": "BDE", "name": "BDE",
"email": "tresorerie.bde@example.com", "email": "tresorerie.bde@example.com",
"membership_fee": 5, "membership_fee": 500,
"membership_duration": "396 00:00:00", "membership_duration": "396 00:00:00",
"membership_start": "213 00:00:00", "membership_start": "213 00:00:00",
"membership_end": "273 00:00:00" "membership_end": "273 00:00:00"
@ -17,7 +17,7 @@
"fields": { "fields": {
"name": "Kfet", "name": "Kfet",
"email": "tresorerie.bde@example.com", "email": "tresorerie.bde@example.com",
"membership_fee": 35, "membership_fee": 3500,
"membership_duration": "396 00:00:00", "membership_duration": "396 00:00:00",
"membership_start": "213 00:00:00", "membership_start": "213 00:00:00",
"membership_end": "273 00:00:00" "membership_end": "273 00:00:00"

View File

@ -17,6 +17,7 @@ class ClubTable(tables.Table):
fields = ('id', 'name', 'email') fields = ('id', 'name', 'email')
row_attrs = { row_attrs = {
'class': 'table-row', 'class': 'table-row',
'id': lambda record: "row-" + str(record.pk),
'data-href': lambda record: record.pk 'data-href': lambda record: record.pk
} }

View File

@ -12,6 +12,8 @@ urlpatterns = [
path('club/<int:pk>/', views.ClubDetailView.as_view(), name="club_detail"), path('club/<int:pk>/', views.ClubDetailView.as_view(), name="club_detail"),
path('club/<int:pk>/add_member/', views.ClubAddMemberView.as_view(), name="club_add_member"), path('club/<int:pk>/add_member/', views.ClubAddMemberView.as_view(), name="club_add_member"),
path('club/create/', views.ClubCreateView.as_view(), name="club_create"), path('club/create/', views.ClubCreateView.as_view(), name="club_create"),
path('club/<int:pk>/update', views.ClubUpdateView.as_view(), name="club_update"),
path('club/<int:pk>/update_pic', views.ClubPictureUpdateView.as_view(), name="club_update_pic"),
path('user/', views.UserListView.as_view(), name="user_list"), path('user/', views.UserListView.as_view(), name="user_list"),
path('user/<int:pk>', views.UserDetailView.as_view(), name="user_detail"), path('user/<int:pk>', views.UserDetailView.as_view(), name="user_detail"),
path('user/<int:pk>/update', views.UserUpdateView.as_view(), name="user_update_profile"), path('user/<int:pk>/update', views.UserUpdateView.as_view(), name="user_update_profile"),

View File

@ -223,10 +223,7 @@ class DeleteAliasView(LoginRequiredMixin, DeleteView):
return self.post(request, *args, **kwargs) return self.post(request, *args, **kwargs)
class ProfilePictureUpdateView(LoginRequiredMixin, FormMixin, DetailView): class PictureUpdateView(LoginRequiredMixin, FormMixin, DetailView):
model = User
template_name = 'member/profile_picture_update.html'
context_object_name = 'user_object'
form_class = ImageForm form_class = ImageForm
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
@ -273,6 +270,12 @@ class ProfilePictureUpdateView(LoginRequiredMixin, FormMixin, DetailView):
return super().form_valid(form) return super().form_valid(form)
class ProfilePictureUpdateView(PictureUpdateView):
model = User
template_name = 'member/profile_picture_update.html'
context_object_name = 'user_object'
class ManageAuthTokens(LoginRequiredMixin, TemplateView): class ManageAuthTokens(LoginRequiredMixin, TemplateView):
""" """
Affiche le jeton d'authentification, et permet de le regénérer Affiche le jeton d'authentification, et permet de le regénérer
@ -329,6 +332,7 @@ class ClubCreateView(LoginRequiredMixin, CreateView):
""" """
model = Club model = Club
form_class = ClubForm form_class = ClubForm
success_url = reverse_lazy('member:club_list')
def form_valid(self, form): def form_valid(self, form):
return super().form_valid(form) return super().form_valid(form)
@ -365,6 +369,23 @@ class ClubDetailView(LoginRequiredMixin, DetailView):
return context return context
class ClubUpdateView(LoginRequiredMixin, UpdateView):
model = Club
context_object_name = "club"
form_class = ClubForm
template_name = "member/club_form.html"
success_url = reverse_lazy("member:club_detail")
class ClubPictureUpdateView(PictureUpdateView):
model = Club
template_name = 'member/club_picture_update.html'
context_object_name = 'club'
def get_success_url(self):
return reverse_lazy('member:club_detail', kwargs={'pk': self.object.id})
class ClubAddMemberView(LoginRequiredMixin, CreateView): class ClubAddMemberView(LoginRequiredMixin, CreateView):
model = Membership model = Membership
form_class = MembershipForm form_class = MembershipForm

View File

@ -70,7 +70,7 @@
"balance": 0, "balance": 0,
"last_negative": null, "last_negative": null,
"is_active": true, "is_active": true,
"display_image": "", "display_image": "pic/default.png",
"created_at": "2020-02-20T20:09:38.615Z" "created_at": "2020-02-20T20:09:38.615Z"
} }
}, },
@ -85,7 +85,7 @@
"balance": 0, "balance": 0,
"last_negative": null, "last_negative": null,
"is_active": true, "is_active": true,
"display_image": "", "display_image": "pic/default.png",
"created_at": "2020-02-20T20:16:14.753Z" "created_at": "2020-02-20T20:16:14.753Z"
} }
}, },

View File

@ -1,62 +1,9 @@
{% extends "base.html" %} {% extends "member/noteowner_detail.html" %}
{% load static %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load pretty_money %}
{% block content %}
<p><a class="btn btn-primary" href="{% url 'member:club_list' %}">Clubs</a></p>
<h3 class="text-center"> Club {{ object.name }}</h3>
<dl>
<dt>{% trans 'Membership starts on' %}</dt>
<dd>{{ club.membership_start }}</dd>
<dt>{% trans 'Membership ends on' %}</dt>
<dd>{{ club.membership_end }}</dd>
<dt>{% trans 'Membership duration' %}</dt>
<dd>{{ club.membership_duration }}</dd>
<dt> Aliases </dt>
<dd>{{ club.note.aliases_set.all }}</dd>
<dt>{% trans 'balance' %}</dt>
<dd>{{ club.note.balance | pretty_money }}</dd>
</dl> {% block profile_info %}
{% include "member/club_info.html" %}
{% endblock %}
{% block profile_content %}
<div class="btn-group" role="group"> {% include "member/club_tables.html" %}
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Ajouter des membres </a> {% endblock %}
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Modifier les informations </a>
<a class="btn btn-primary" href="{% url 'member:club_add_member' pk=object.pk %}"> Ajouter des roles </a>
</div>
<div class="accordion" id="accordionExample">
<div class="card">
<div class="card-header" id="headingOne">
<h5 class="mb-0">
<button class="btn btn-link" type="button" data-toggle="collapse" data-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<i class="fa fa-users"></i> Membres du club
</button>
</h5>
</div>
<div id="collapseOne" class="collapse show" aria-labelledby="headingOne" data-parent="#accordionExample">
<div class="card-body">
{% render_table member_list %}
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingTwo">
<h5 class="mb-0">
<button class="btn btn-link collapsed" type="button" data-toggle="collapse" data-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</button>
</h5>
</div>
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordionExample">
<div class="card-body">
{% render_table history_list %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -3,7 +3,6 @@
{% load i18n %} {% load i18n %}
{% load crispy_forms_tags %} {% load crispy_forms_tags %}
{% block content %} {% block content %}
<p><a class="btn btn-default" href="{% url 'note:template_list' %}">{% trans "Clubs list" %}</a></p>
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
{{form|crispy}} {{form|crispy}}

View File

@ -0,0 +1,32 @@
{% load i18n static pretty_money %}
<div class="card bg-light shadow">
<div class="card-top text-center">
<a href="{% url 'member:club_update_pic' club.pk %}">
<img src="{{ club.note.display_image.url }}" class="img-thumbnail mt-2" >
</a>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.name}}</dd>
<dt class="col-xl-6">{% trans 'membership start'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_start }}</dd>
<dt class="col-xl-6">{% trans 'membership end'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_end }}</dd>
<dt class="col-xl-6">{% trans 'membership duration'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_duration }}</dd>
<dt class="col-xl-6">{% trans 'membership fee'|capfirst %}</dt>
<dd class="col-xl-6">{{ club.membership_fee|pretty_money }}</dd>
<dt class="col-xl-6"><a href="{% url 'member:user_alias' club.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
<dt class="col-xl-3">{% trans 'email'|capfirst %}</dt>
<dd class="col-xl-9"><a href="mailto:{{ club.email }}">{{ club.email}}</a></dd>
</dl>
</div>
</div>

View File

@ -2,15 +2,65 @@
{% load render_table from django_tables2 %} {% load render_table from django_tables2 %}
{% load i18n %} {% load i18n %}
{% block content %} {% block content %}
<div class="row justify-content-center mb-4">
{% render_table table %} <div class="col-md-10 text-center">
<h4>
<a class="btn btn-primary" href="{% url 'member:club_create' %}">{% trans "New club" %}</a> {% trans "search clubs" %}
</h4>
<input class="form-control mx-auto w-25" type="text" onkeyup="search_field_moved();return(false);" id="search_field"/>
<hr>
<a class="btn btn-primary text-center my-4" href="{% url 'member:club_create' %}">{% trans "Créer un club" %}</a>
</div>
</div>
<div class="row justify-content-center">
<div class="col-md-10">
<div class="card card-border shadow">
<div class="card-header text-center">
<h5> {% trans "club listing "%}</h5>
</div>
<div class="card-body px-0 py-0" id="club_table">
{% render_table table %}
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block extrajavascript %}
<script type="text/javascript"> <script type="text/javascript">
function getInfo() {
var asked = $("#search_field").val();
/* on ne fait la requête que si on a au moins un caractère pour chercher */
var sel = $(".table-row");
if (asked.length >= 1) {
$.getJSON("/api/members/club/?format=json&search="+asked, function(buttons){
let selected_id = buttons.results.map((a => "#row-"+a.id));
console.log(selected_id.join());
$(".table-row,"+selected_id.join()).show();
$(".table-row").not(selected_id.join()).hide();
});
}else{
// show everything
$('table tr').show();
}
}
var timer;
var timer_on;
/* Fontion appelée quand le texte change (délenche le timer) */
function search_field_moved(secondfield) {
if (timer_on) { // Si le timer a déjà été lancé, on réinitialise le compteur.
clearTimeout(timer);
timer = setTimeout("getInfo(" + secondfield + ")", 300);
}
else { // Sinon, on le lance et on enregistre le fait qu'il tourne.
timer = setTimeout("getInfo(" + secondfield + ")", 300);
timer_on = true;
}
}
// clickable row
$(document).ready(function($) { $(document).ready(function($) {
$(".table-row").click(function() { $(".table-row").click(function() {
window.document.location = $(this).data("href"); window.document.location = $(this).data("href");

View File

@ -0,0 +1,10 @@
{% extends "member/club_detail.html" %}
{% load i18n static pretty_money django_tables2 crispy_forms_tags %}
{% block profile_info %}
{% include "member/club_info.html" %}
{% endblock%}
{% block profile_content%}
{% include "member/picture_update.html" %}
{% endblock%}

View File

@ -0,0 +1,31 @@
{% load render_table from django_tables2 %}
{% load i18n %}
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "Member of the Club" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table member_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
<div id="history_list">
{% render_table history_list %}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,27 @@
{% extends "base.html" %}
{% load static %}
{% load i18n %}
{% load render_table from django_tables2 %}
{% load pretty_money %}
{% block content %}
<div class="row mt-4">
<div class="col-md-3 mb-4">
{% block profile_info %}
{% endblock %}
</div>
<div class="col-md-9">
{% block profile_content %}
{% endblock %}
</div>
</div>
{% endblock %}
{% block extrajavascript %}
<script>
function refreshhistory() {
$("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list");
$("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos");
}
</script>
{% endblock %}

View File

@ -0,0 +1,95 @@
{% load i18n crispy_forms_tags %}
{% block profile_content %}
<div class="text-center">
<form method="post" enctype="multipart/form-data" id="formUpload">
{% csrf_token %}
{{ form |crispy }}
</form>
</div>
<!-- MODAL TO CROP THE IMAGE -->
<div class="modal fade" id="modalCrop">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img src="" id="modal-image" style="max-width: 100%;">
</div>
<div class="modal-footer">
<div class="btn-group pull-left" role="group">
<button type="button" class="btn btn-default" id="js-zoom-in">
<span class="glyphicon glyphicon-zoom-in"></span>
</button>
<button type="button" class="btn btn-default js-zoom-out">
<span class="glyphicon glyphicon-zoom-out"></span>
</button>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
<button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extracss %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.css" rel="stylesheet">
{% endblock %}
{% block extrajavascript%}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.1/dist/jquery-cropper.min.js"></script>
<script>
$(function () {
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
$("#id_image").change(function (e) {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#modal-image").attr("src", e.target.result);
$("#modalCrop").modal("show");
}
reader.readAsDataURL(this.files[0]);
}
});
/* SCRIPTS TO HANDLE THE CROPPER BOX */
var $image = $("#modal-image");
var cropBoxData;
var canvasData;
$("#modalCrop").on("shown.bs.modal", function () {
$image.cropper({
viewMode: 1,
aspectRatio: 1/1,
minCropBoxWidth: 200,
minCropBoxHeight: 200,
ready: function () {
$image.cropper("setCanvasData", canvasData);
$image.cropper("setCropBoxData", cropBoxData);
}
});
}).on("hidden.bs.modal", function () {
cropBoxData = $image.cropper("getCropBoxData");
canvasData = $image.cropper("getCanvasData");
$image.cropper("destroy");
});
$(".js-zoom-in").click(function () {
$image.cropper("zoom", 0.1);
});
$(".js-zoom-out").click(function () {
$image.cropper("zoom", -0.1);
});
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
$(".js-crop-and-upload").click(function () {
var cropData = $image.cropper("getData");
$("#id_x").val(cropData["x"]);
$("#id_y").val(cropData["y"]);
$("#id_height").val(cropData["height"]);
$("#id_width").val(cropData["width"]);
$("#formUpload").submit();
});
});
</script>
{% endblock %}

View File

@ -1,97 +1,9 @@
{% extends "base.html" %} {% extends "member/noteowner_detail.html" %}
{% load i18n static pretty_money django_tables2 %}
{% block content %} {% block profile_info %}
<div class="row mt-4"> {% include "member/profile_info.html" %}
<div class="col-md-3 mb-4">
<div class="card bg-light shadow">
<div class="card-top text-center">
<a href="{% url 'member:user_update_pic' object.pk %}">
<img src="{{ object.note.display_image.url }}" class="img-thumbnail mt-2" >
</a>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
<dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
<dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.username }}</dd>
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}">
{% trans 'Change password' %}
</a>
</dd>
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.section }}</dd>
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.address }}</dd>
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
<dt class="col-xl-6"> <a href="{% url 'member:user_alias' object.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
</dl>
{% if object.pk == user.pk %}
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
{% endif %}
</div>
<div class="card-footer text-center">
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
{% url 'member:user_detail' object.pk as user_profile_url %}
{%if request.get_full_path != user_profile_url %}
<a class="btn btn-primary btn-sm" href="{{ user_profile_url }}">{% trans 'View Profile' %}</a>
{% endif %}
</div>
</div>
</div>
<div class="col-md-9">
{% block profile_content %}
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "View my memberships" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table club_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
<div id="history_list">
{% render_table history_list %}
</div>
</div>
</div>
</div>
{% endblock %}
</div>
</div>
{% endblock %} {% endblock %}
{% block extrajavascript %} {% block profile_content %}
<script> {% include "member/profile_tables.html" %}
function refreshHistory() {
$("#history_list").load("{% url 'member:user_detail' pk=object.pk %} #history_list");
$("#profile_infos").load("{% url 'member:user_detail' pk=object.pk %} #profile_infos");
}
</script>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,48 @@
{% load i18n static pretty_money %}
<div class="card bg-light shadow">
<div class="card-top text-center">
<a href="{% url 'member:user_update_pic' object.pk %}">
<img src="{{ object.note.display_image.url }}" class="img-thumbnail mt-2" >
</a>
</div>
<div class="card-body" id="profile_infos">
<dl class="row">
<dt class="col-xl-6">{% trans 'name'|capfirst %}, {% trans 'first name' %}</dt>
<dd class="col-xl-6">{{ object.last_name }} {{ object.first_name }}</dd>
<dt class="col-xl-6">{% trans 'username'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.username }}</dd>
<dt class="col-xl-6">{% trans 'password'|capfirst %}</dt>
<dd class="col-xl-6">
<a class="small" href="{% url 'password_change' %}">
{% trans 'Change password' %}
</a>
</dd>
<dt class="col-xl-6">{% trans 'section'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.section }}</dd>
<dt class="col-xl-6">{% trans 'address'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.profile.address }}</dd>
<dt class="col-xl-6">{% trans 'balance'|capfirst %}</dt>
<dd class="col-xl-6">{{ object.note.balance | pretty_money }}</dd>
<dt class="col-xl-6"> <a href="{% url 'member:user_alias' object.pk %}">{% trans 'aliases'|capfirst %}</a></dt>
<dd class="col-xl-6 text-truncate">{{ object.note.alias_set.all|join:", " }}</dd>
</dl>
{% if object.pk == user.pk %}
<a class="small" href="{% url 'member:auth_token' %}">{% trans 'Manage auth token' %}</a>
{% endif %}
</div>
<div class="card-footer text-center">
<a class="btn btn-primary btn-sm" href="{% url 'member:user_update_profile' object.pk %}">{% trans 'Update Profile' %}</a>
{% url 'member:user_detail' object.pk as user_profile_url %}
{%if request.get_full_path != user_profile_url %}
<a class="btn btn-primary btn-sm" href="{{ user_profile_url }}">{% trans 'View Profile' %}</a>
{% endif %}
</div>
</div>

View File

@ -1,97 +1,10 @@
{% extends "member/profile_detail.html" %} {% extends "member/noteowner_detail.html" %}
{% load i18n static pretty_money django_tables2 crispy_forms_tags %} {% load i18n static pretty_money django_tables2 crispy_forms_tags %}
{% block profile_content %} {% block profile_info %}
<div class="text-center"> {% include "member/profile_info.html" %}
<form method="post" enctype="multipart/form-data" id="formUpload"> {% endblock%}
{% csrf_token %}
{{ form |crispy }}
</form>
</div>
<!-- MODAL TO CROP THE IMAGE -->
<div class="modal fade" id="modalCrop">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<img src="" id="modal-image" style="max-width: 100%;">
</div>
<div class="modal-footer">
<div class="btn-group pull-left" role="group">
<button type="button" class="btn btn-default" id="js-zoom-in">
<span class="glyphicon glyphicon-zoom-in"></span>
</button>
<button type="button" class="btn btn-default js-zoom-out">
<span class="glyphicon glyphicon-zoom-out"></span>
</button>
</div>
<button type="button" class="btn btn-default" data-dismiss="modal">Nevermind</button>
<button type="button" class="btn btn-primary js-crop-and-upload">Crop and upload</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extracss %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.css" rel="stylesheet">
{% endblock %}
{% block extrajavascript%} {% block profile_content%}
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script> {% include "member/picture_update.html" %}
<script src="https://cdn.jsdelivr.net/npm/jquery-cropper@1.0.1/dist/jquery-cropper.min.js"></script> {% endblock%}
<script>
$(function () {
/* SCRIPT TO OPEN THE MODAL WITH THE PREVIEW */
$("#id_image").change(function (e) {
if (this.files && this.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$("#modal-image").attr("src", e.target.result);
$("#modalCrop").modal("show");
}
reader.readAsDataURL(this.files[0]);
}
});
/* SCRIPTS TO HANDLE THE CROPPER BOX */
var $image = $("#modal-image");
var cropBoxData;
var canvasData;
$("#modalCrop").on("shown.bs.modal", function () {
$image.cropper({
viewMode: 1,
aspectRatio: 1/1,
minCropBoxWidth: 200,
minCropBoxHeight: 200,
ready: function () {
$image.cropper("setCanvasData", canvasData);
$image.cropper("setCropBoxData", cropBoxData);
}
});
}).on("hidden.bs.modal", function () {
cropBoxData = $image.cropper("getCropBoxData");
canvasData = $image.cropper("getCanvasData");
$image.cropper("destroy");
});
$(".js-zoom-in").click(function () {
$image.cropper("zoom", 0.1);
});
$(".js-zoom-out").click(function () {
$image.cropper("zoom", -0.1);
});
/* SCRIPT TO COLLECT THE DATA AND POST TO THE SERVER */
$(".js-crop-and-upload").click(function () {
var cropData = $image.cropper("getData");
$("#id_x").val(cropData["x"]);
$("#id_y").val(cropData["y"]);
$("#id_height").val(cropData["height"]);
$("#id_width").val(cropData["width"]);
$("#formUpload").submit();
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,31 @@
{% load render_table from django_tables2 %}
{% load i18n %}
<div class="accordion shadow" id="accordionProfile">
<div class="card">
<div class="card-header position-relative" id="clubListHeading">
<a class="btn btn-link stretched-link font-weight-bold"
data-toggle="collapse" data-target="#clubListCollapse"
aria-expanded="true" aria-controls="clubListCollapse">
<i class="fa fa-users"></i> {% trans "View my memberships" %}
</a>
</div>
<div id="clubListCollapse" class="collapse show" style="overflow:auto hidden" aria-labelledby="clubListHeading" data-parent="#accordionProfile">
{% render_table club_list %}
</div>
</div>
<div class="card">
<div class="card-header position-relative" id="historyListHeading">
<a class="btn btn-link stretched-link collapsed font-weight-bold"
data-toggle="collapse" data-target="#historyListCollapse"
aria-expanded="false" aria-controls="historyListCollapse">
<i class="fa fa-euro"></i> {% trans "Transaction history" %}
</a>
</div>
<div id="historyListCollapse" class="collapse" style="overflow:auto hidden" aria-labelledby="historyListHeading" data-parent="#accordionProfile">
<div id="history_list">
{% render_table history_list %}
</div>
</div>
</div>
</div>