Delete unused image, adding profile and minor jumper's page improvement
|
@ -30,7 +30,6 @@ ALLOWED_HOSTS = []
|
|||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
|
@ -42,6 +41,7 @@ INSTALLED_APPS = [
|
|||
'jumpers',
|
||||
'followup',
|
||||
'tools',
|
||||
'profiles',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
|
|
@ -18,16 +18,23 @@ from django.urls import include, path
|
|||
|
||||
import jumpers.urls
|
||||
import Ultron.views
|
||||
import profiles.urls
|
||||
|
||||
urlpatterns = [
|
||||
# Profile list
|
||||
path(r"profile/", include(profiles.urls.profile_urlpatterns)),
|
||||
|
||||
# Jumpers management
|
||||
path(r"jumper/", include(jumpers.urls.jumper_urlpatterns)),
|
||||
path(r"club/", include(jumpers.urls.club_urlpatterns)),
|
||||
|
||||
# path(r"search/", config.views.search, name="global_search"),
|
||||
# login & logout
|
||||
# path(r"login/", Ultron.views.login, name="login"),
|
||||
|
||||
# Login & logout
|
||||
path(r"login/", Ultron.views.login, name="login"),
|
||||
path(r"logout/", Ultron.views.logout, name="logout"),
|
||||
path(r"", Ultron.views.home, name="home"),
|
||||
|
||||
# Administration
|
||||
path('admin/', admin.site.urls),
|
||||
]
|
||||
|
|
|
@ -13,40 +13,41 @@ from django.http import HttpResponseRedirect
|
|||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from profiles.models import Profile
|
||||
|
||||
# def login(request):
|
||||
# """
|
||||
# Formulaire d'authentifictation.
|
||||
# """
|
||||
# club_list = Club.objects.all()
|
||||
|
||||
# if request.method == "POST":
|
||||
# username = request.POST["login"]
|
||||
# password = request.POST["password"]
|
||||
def login(request):
|
||||
"""
|
||||
Formulaire d'authentifictation.
|
||||
"""
|
||||
|
||||
# user = authenticate(username=username, password=password)
|
||||
if request.method == "POST":
|
||||
username = request.POST["login"]
|
||||
password = request.POST["password"]
|
||||
|
||||
# if user is not None: # Pq pas "if user:" ??
|
||||
# if user.is_active:
|
||||
# auth_login(request, user)
|
||||
# try:
|
||||
# profile = Profile.objects.get(user=user)
|
||||
# request.session["profileid"] = profile.id
|
||||
# request.session["template"] = profile.template_color
|
||||
# request.session["sidebar"] = profile.sidebar_color
|
||||
# request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
||||
# except Exception:
|
||||
# pass
|
||||
# request.session["clubid"] = request.POST.get("clubid", None)
|
||||
# return HttpResponseRedirect("/")
|
||||
# else:
|
||||
# context = {"message": "Account disabled.", "clubs": club_list}
|
||||
# else:
|
||||
# context = {"message": "Wrong login/password.", "clubs": club_list}
|
||||
# else:
|
||||
# context = {"clubs": club_list}
|
||||
user = authenticate(username=username, password=password)
|
||||
|
||||
# return render(request, "login.html", context)
|
||||
if user is not None: # Pq pas "if user:" ??
|
||||
if user.is_active:
|
||||
auth_login(request, user)
|
||||
try:
|
||||
profile = Profile.objects.get(user=user)
|
||||
request.session["profileid"] = profile.id
|
||||
request.session["template"] = profile.template_color
|
||||
request.session["sidebar"] = profile.sidebar_color
|
||||
request.session["is_sidebar_minified"] = profile.is_sidebar_minified
|
||||
except Exception:
|
||||
pass
|
||||
request.session["clubid"] = request.POST.get("clubid", None)
|
||||
return HttpResponseRedirect("/")
|
||||
else:
|
||||
context = {"message": "Account disabled."}
|
||||
else:
|
||||
context = {"message": "Wrong login/password."}
|
||||
else:
|
||||
context = {}
|
||||
|
||||
return render(request, "login.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.shortcuts import render
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
# Create your views here.
|
||||
|
|
|
@ -1,38 +1,36 @@
|
|||
from django.shortcuts import render, get_object_or_404
|
||||
from django.http import HttpResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from .models import Club, Jumper
|
||||
from followup.models import Chrono, LearnedSkill
|
||||
|
||||
|
||||
# @login_required
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def club_listing(request):
|
||||
"""
|
||||
Liste tous les clubs connus
|
||||
"""Liste tous les clubs connus
|
||||
"""
|
||||
club_list = Club.objects.all()
|
||||
context = {"club_list": club_list}
|
||||
return render(request, "clubs/list.html", context)
|
||||
|
||||
|
||||
# @login_required
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def jumper_listing(request):
|
||||
"""
|
||||
Liste tous les gymnasts connus
|
||||
"""Liste tous les gymnasts connus
|
||||
"""
|
||||
jumper_list = Jumper.objects.all()
|
||||
context = {"jumper_list": jumper_list}
|
||||
return render(request, "jumpers/list.html", context)
|
||||
|
||||
|
||||
# @login_required
|
||||
@login_required
|
||||
@require_http_methods(["GET"])
|
||||
def jumper_details(request, jumperid):
|
||||
"""
|
||||
Récupère toutes les informations d'un gymnaste.
|
||||
"""Récupère toutes les informations d'un gymnaste.
|
||||
"""
|
||||
jumper = get_object_or_404(Jumper, pk=jumperid)
|
||||
learnedskills_list = LearnedSkill.objects.filter(jumper=jumperid).order_by('-date')[:8]
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
"""Administration des profils utilisateurs."""
|
||||
|
||||
from django.contrib import admin
|
||||
from .models import Profile
|
||||
|
||||
|
||||
class ProfileAdmin(admin.ModelAdmin):
|
||||
model = Profile
|
||||
list_display = ("user", "template_color", "sidebar_color")
|
||||
|
||||
|
||||
admin.site.register(Profile, ProfileAdmin)
|
|
@ -0,0 +1,6 @@
|
|||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ProfileConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'profiles'
|
|
@ -0,0 +1,26 @@
|
|||
# coding=UTF-8
|
||||
|
||||
from django import forms
|
||||
from datetime import date
|
||||
from .models import Profile
|
||||
|
||||
|
||||
class ProfileForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = (
|
||||
"template_color",
|
||||
"sidebar_color",
|
||||
"is_sidebar_minified",
|
||||
)
|
||||
widgets = {
|
||||
"template_color": forms.Select(attrs={"class": "form-control"}),
|
||||
"sidebar_color": forms.Select(attrs={"class": "form-control"}),
|
||||
"is_sidebar_minified": forms.CheckboxInput(
|
||||
attrs={
|
||||
"class": "bootstrap-switch mt-0",
|
||||
"data-on-label": "<i class='tim-icons icon-check-2 text-success'></i>",
|
||||
"data-off-label": "<i class='tim-icons icon-simple-remove text-danger'></i>",
|
||||
}
|
||||
),
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
# Generated by Django 3.2.8 on 2021-11-02 15:27
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('template_color', models.PositiveSmallIntegerField(choices=[(0, 'Dark'), (1, 'Light')], default=0, verbose_name='Template')),
|
||||
('sidebar_color', models.PositiveSmallIntegerField(choices=[(0, 'Purple'), (1, 'Blue'), (2, 'Green'), (3, 'Orange'), (4, 'Red')], default=0, verbose_name='Sidebar')),
|
||||
('is_sidebar_minified', models.BooleanField(default=False)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
|
@ -0,0 +1,43 @@
|
|||
"""Extension et gestion des profils utilisateurs.
|
||||
|
||||
Les profils peuvent enregistrer les informations suivantes:
|
||||
|
||||
* le type de template,
|
||||
* la couleur de la barre de navigation
|
||||
* si la barre de navigation doit être cachée ou non
|
||||
"""
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
"""Classe étendant les informations des utilisateurs/entraineurs de l'application.
|
||||
|
||||
References:
|
||||
* https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
|
||||
"""
|
||||
|
||||
TEMPLATE_CHOICES = ((0, "Dark"), (1, "Light"))
|
||||
SIDEBAR_CHOICES = (
|
||||
(0, "Purple"),
|
||||
(1, "Blue"),
|
||||
(2, "Green"),
|
||||
(3, "Orange"),
|
||||
(4, "Red"),
|
||||
)
|
||||
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
template_color = models.PositiveSmallIntegerField(
|
||||
choices=TEMPLATE_CHOICES, verbose_name="Template", default=0
|
||||
)
|
||||
sidebar_color = models.PositiveSmallIntegerField(
|
||||
choices=SIDEBAR_CHOICES, verbose_name="Sidebar", default=0
|
||||
)
|
||||
is_sidebar_minified = models.BooleanField(default=False)
|
||||
|
||||
def __str__(self):
|
||||
return "%s %s" % (self.user.first_name, self.user.last_name)
|
|
@ -0,0 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
|
@ -0,0 +1,10 @@
|
|||
"""URLs définissant la gestion des profils utilisateurs."""
|
||||
|
||||
from django.urls import path, re_path
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
profile_urlpatterns = [
|
||||
path(r"edit/", views.profile_update, name="profile_update"),
|
||||
]
|
|
@ -0,0 +1,45 @@
|
|||
"""Vues de gestion des profils utilisateurs."""
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponseRedirect, HttpResponse
|
||||
from django.shortcuts import get_object_or_404, render
|
||||
from django.views.decorators.http import require_http_methods
|
||||
|
||||
from .forms import ProfileForm
|
||||
from .models import Profile
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
@login_required
|
||||
@require_http_methods(["GET", "POST"])
|
||||
def profile_update(request):
|
||||
"""Modification du profil de l'utilisateur connecté
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
profile = request.user.profile
|
||||
except Exception: # don't do this !
|
||||
profile = Profile.objects.create(user=request.user)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ProfileForm(request.POST, instance=profile)
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
|
||||
request.session['template'] = profile.template_color
|
||||
request.session['sidebar'] = profile.sidebar_color
|
||||
request.session['is_sidebar_minified'] = profile.is_sidebar_minified
|
||||
|
||||
return HttpResponseRedirect("/")
|
||||
|
||||
else:
|
||||
form = ProfileForm(instance=profile)
|
||||
|
||||
context = {
|
||||
"form": form,
|
||||
}
|
||||
return render(request, 'profiles/update.html', context)
|
Before Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 344 KiB |
Before Width: | Height: | Size: 655 KiB |
Before Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 2.1 MiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 165 KiB |
Before Width: | Height: | Size: 83 KiB |
|
@ -42,8 +42,7 @@
|
|||
<link href='https://api.mapbox.com/mapbox.js/v3.2.0/mapbox.css' rel='stylesheet' />
|
||||
</head>
|
||||
|
||||
<!-- <body class="sidebar-mini {% if request.session.template == 1 %}white-content{% endif %}"> -->
|
||||
<body class="sidebar-mini white-content">
|
||||
<body class="sidebar-mini {% if request.session.template == 1 %}white-content{% endif %}">
|
||||
<div class="wrapper">
|
||||
<div class="navbar-minimize-fixed">
|
||||
<button class="minimize-sidebar btn btn-link btn-just-icon">
|
||||
|
@ -100,7 +99,7 @@
|
|||
</button>
|
||||
<div class="collapse navbar-collapse" id="navigation">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="search-bar input-group">
|
||||
<!-- <li class="search-bar input-group">
|
||||
<button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal">
|
||||
<i class="tim-icons icon-zoom-split"></i>
|
||||
<span class="d-lg-none d-md-block">Search</span>
|
||||
|
@ -114,16 +113,19 @@
|
|||
<ul class="dropdown-menu dropdown-menu-right dropdown-navbar">
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</li> -->
|
||||
<li class="dropdown nav-item">
|
||||
<a href="#" class="dropdown-toggle nav-link" data-toggle="dropdown">
|
||||
<div class="photo">
|
||||
<img src="{% static '/img/mike.jpg' %}" alt="Profile Photo">
|
||||
<img src="{% static '/img/default-avatar.png' %}" alt="Profile Photo">
|
||||
</div>
|
||||
<b class="caret d-none d-lg-block d-xl-block"></b>
|
||||
<p class="d-lg-none">Log out</p>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-navbar">
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'profile_update' %}" class="nav-item dropdown-item">Profile</a>
|
||||
</li>
|
||||
<li class="dropdown-divider"></li>
|
||||
<li class="nav-link">
|
||||
<a href="{% url 'logout' %}" class="nav-item dropdown-item">Log out</a>
|
||||
|
@ -261,7 +263,7 @@
|
|||
sidebar_mini_active = false;
|
||||
{% endif %}
|
||||
{% if request.session.template == 0 %}
|
||||
white_color = true;
|
||||
white_color = false;
|
||||
{% else %}
|
||||
white_color = true;
|
||||
{% endif %}
|
||||
|
@ -279,7 +281,7 @@
|
|||
{% elif request.session.sidebar == 4 %}
|
||||
color = 'red';
|
||||
{% else %}
|
||||
color = 'red'
|
||||
color = 'purple'
|
||||
{% endif %}
|
||||
$sidebar.attr('data', color);
|
||||
$main_panel.attr('data', color);
|
||||
|
|
|
@ -10,23 +10,10 @@
|
|||
<div class="col-md-9">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4>Hi {{ user.first_name }} !</h4>
|
||||
<h4>Hi {{ user.username }} !</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if error %}
|
||||
<p class="text-danger">{{ error }}</p>
|
||||
{% endif %}
|
||||
{% if number_of_courses %}
|
||||
We are in the <b>{{ week_number }}th week</b> of the season and you've {{ number_of_courses }} courses the next two days : <br />
|
||||
<ul>
|
||||
{% for course in courses_list %}
|
||||
<li><a href="/course/{{ course.id }}/(date)">{{ course.get_iso_day_number_display }} from {{ course.hour_begin|time:"H:i" }} to {{ course.hour_end|time:"H:i" }} ({{ course.club.acronym }})</a></li >
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if number_unreaded_message %}
|
||||
You have <a href="{% url 'received_messages' %}">{{ number_unreaded_message }}</a> unread messsage{% if number_unreaded_message > 1 %}s{% endif %}.
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -34,7 +21,7 @@
|
|||
<div class="card mb-2">
|
||||
<div class="card-body">
|
||||
<div class="w-lg m-x-auto">
|
||||
<canvas id="chartjs_year_completude" style="width: 238px; height: 238px"></canvas>
|
||||
(line 1 cadre 2)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,28 +32,10 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="">Next events</h4>
|
||||
<h4 class="">(line 2 cadre 1)</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if event_list %}
|
||||
<table class="table table-condensed table-sm table-striped">
|
||||
<tbody>
|
||||
{% for event in event_list %}
|
||||
<tr>
|
||||
<td class="text-left">
|
||||
<a href="{% url 'event_details' event.id %}">{{ event.name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ event.datebegin | date:"j M"}}
|
||||
</td>
|
||||
<td class="text-right"><span class="text-{% if event.number_of_week_from_today > 12 %}success{% elif event.number_of_week_from_today > 9 %}info{% elif event.number_of_week_from_today > 6 %}warning{% else %}danger{% endif %}">{{event.number_of_week_from_today}}w</span></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
No planified event.
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -74,29 +43,10 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="">Next Unavailability</h4>
|
||||
<h4 class="">(line 2 celle 2)</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if unavailable_list %}
|
||||
<table class="table table-condensed table-sm table-striped">
|
||||
<tbody>
|
||||
{% for unavailable in unavailable_list %}
|
||||
<tr>
|
||||
<td class="text-left">
|
||||
<a class="list-group-item" href="/unavailability/{{unavailable.id}}">
|
||||
{% if unavailable.datebegin == unavailable.dateend %}
|
||||
{{ unavailable.datebegin | date:"j M" }}
|
||||
{% else %}
|
||||
{{ unavailable.datebegin | date:"j M"}} - {{ unavailable.dateend | date:"j M"}}
|
||||
{% endif %}
|
||||
</a>
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
No unavailability planified.
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -104,74 +54,17 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="">Next birthdays</h4>
|
||||
<h4 class="">(line 2 cadre 3)</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-condensed table-sm table-striped">
|
||||
<tbody>
|
||||
{% for gymnast in birthday_list %}
|
||||
<tr>
|
||||
<td class="text-left"><a href="{% url 'gymnast_details' gymnast.id %}">{{ gymnast.firstname }}</a></td>
|
||||
<td class="">{{ gymnast.birthdate | date:"j M"}}</td>
|
||||
<td class="text-right">{{ gymnast.nextAge }} years</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4>Courses</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% for course in course_list %}
|
||||
<a class="list-group-item" href="#">
|
||||
<span class="list-group-progress" style="width: {% widthratio course.2 course.1 100 %}%;"></span>
|
||||
<span class="pull-right text-muted">{{ course.2 }}/{{ course.1 }}</span>
|
||||
{{ course.0.get_diso_day_number_display }} <span class="text-muted">({{ course.0.hour_begin}} - {{ course.0.hour_end }})</span>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block footerscript %}
|
||||
<script type="text/javascript">
|
||||
new Chart(document.getElementById("chartjs_year_completude"),{
|
||||
type: "doughnut",
|
||||
data: {
|
||||
datasets:[
|
||||
{
|
||||
borderWidth: 1,
|
||||
data:[
|
||||
{{ donecourses }},
|
||||
{{ courses_left }}
|
||||
],
|
||||
backgroundColor:[
|
||||
"#1bc98e", /*"#1ca8dd",*/
|
||||
"#FF2F92" /*"#1bc98e"*/
|
||||
]
|
||||
}
|
||||
],
|
||||
labels: [
|
||||
'Given courses ',
|
||||
'Total courses '
|
||||
],
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
cutoutPercentage: 55,
|
||||
maintainAspectRatio: false,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock%}
|
||||
|
|
|
@ -35,17 +35,17 @@
|
|||
<div class="col-12 col-sm-4 col-md-4 col-lg-4">
|
||||
<div class="table-responsive pb-0"></div>
|
||||
{% if learnedskills_list %}
|
||||
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="maintable">
|
||||
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="skilltable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="header text-left" style="width: 45%">Date</th>
|
||||
<th class="header text-left" style="width: 65%">Skill</th>
|
||||
<th class="header text-left" style="width: 40%">Date</th>
|
||||
<th class="header text-left" style="width: 60%">Skill</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for skill in learnedskills_list %}
|
||||
<tr>
|
||||
<td class="text-left">{{ skill.date | date:"d F Y" }}</a></td>
|
||||
<td class="text-left">{{ skill.date | date:"d-m-Y" }}</a></td>
|
||||
<td class="text-left">{{ skill.skill }}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -63,18 +63,18 @@
|
|||
<div class="col-12 col-sm-4 col-md-4 card">
|
||||
<div class="table-responsive pb-0">
|
||||
{% if chronos_list %}
|
||||
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="maintable">
|
||||
<table class="table tablesorter table-striped table-condensed" data-sort="table" id="chronotable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="header text-left" style="width: 45%">Date</th>
|
||||
<th class="header text-left" style="width: 20%">Type</th>
|
||||
<th class="header text-left" style="width: 35%">Tof</th>
|
||||
<th class="header text-left" style="width: 35%">Date</th>
|
||||
<th class="header text-left" style="width: 35%">Type</th>
|
||||
<th class="header text-left" style="width: 30%">Tof</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for chrono in chronos_list %}
|
||||
<tr>
|
||||
<td class="text-left">{{ chrono.date | date:"d F Y" }}</a></td>
|
||||
<td class="text-left">{{ chrono.date | date:"d-m-Y" }}</a></td>
|
||||
<td class="text-left">{{ chrono.get_type_display }}</a></td>
|
||||
<td class="text-right">{{ chrono.tof }}</a></td>
|
||||
</tr>
|
||||
|
@ -84,7 +84,7 @@
|
|||
{% else %}
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>There are no places corresponding to your criterias</td>
|
||||
<td>No information found</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endif %}
|
||||
|
@ -99,8 +99,20 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footerscript %}
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
$('#skilltable').tablesorter({
|
||||
dateFormat: "uk",
|
||||
})
|
||||
|
||||
$('#chronotable').tablesorter({
|
||||
dateFormat: "uk",
|
||||
})
|
||||
});
|
||||
|
||||
new Chart(document.getElementById("chartjs_routine"),{
|
||||
type: 'line',
|
||||
data:{
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<div class="container">
|
||||
<div class="col-lg-4 col-md-6 ml-auto mr-auto">
|
||||
<form class="form" action="/login/" method="post" if="formulaire">
|
||||
{% csrf_token %}
|
||||
<div class="card card-login card-white">
|
||||
<div class="card-header">
|
||||
<img src="{% static "img/card-danger.png" %}" alt="">
|
||||
|
@ -61,18 +62,6 @@
|
|||
</div>
|
||||
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
|
||||
</div>
|
||||
<!-- {% if clubs.count > 0 %}
|
||||
<div class="form-group">
|
||||
<label for="password" class="col-sm-2 control-label">Club</label>
|
||||
<div class="col-sm-6">
|
||||
<select name="clubid" class="custom-select custom-select-sm">
|
||||
{% for club in clubs %}
|
||||
<option value="{{club.id}}">{{club}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %} -->
|
||||
{% if message %}
|
||||
<p class="text-danger"><b>{{message}}</b></p>
|
||||
{% endif %}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-sm-10 col-md-7 col-lg-6 col-xl-5">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">Edit User Profile</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form action="{% url 'profile_update' %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
|
||||
{% csrf_token %}
|
||||
<div class="form-group row">
|
||||
<label for="id_template_color" class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4 col-form-label">Template Black</label>
|
||||
<div class="col-8 col-sm-7 col-md-6 col-lg-5 col-xl-4 {% if form.template_color.errors %}has-danger{% endif %}">
|
||||
{{ form.template_color }}
|
||||
{% if form.template_color.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.template_color.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="id_is_sidebar_minified" class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4 col-form-label">Sidebar active</label>
|
||||
<div class="col-8 col-sm-2 col-md-2 col-lg-2 col-xl-2 {% if form.is_sidebar_minified.errors %}has-danger{% endif %}">
|
||||
{{ form.is_sidebar_minified }}
|
||||
{% if form.is_sidebar_minified.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.is_sidebar_minified.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label for="id_sidebar_color" class="col-4 col-sm-4 col-md-4 col-lg-4 col-xl-4 col-form-label">Sidebar Color</label>
|
||||
<div class="col-8 col-sm-7 col-md-6 col-lg-5 col-xl-4 {% if form.sidebar_color.errors %}has-danger{% endif %}">
|
||||
{{ form.sidebar_color }}
|
||||
{% if form.sidebar_color.errors %} <span class="btn btn-sm btn-danger-outline">{% for error in form.sidebar_color.errors %}{{error}}{% endfor %}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<div class="form-group text-center">
|
||||
<input type="submit" value="Save" class="btn btn-warning" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
blackDashboard.initDateTimePicker();
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|