Compare commits

...

30 Commits

Author SHA1 Message Date
Gregory Trullemans 2bb2fb55eb Add stability templates and URLs 2023-08-20 12:39:46 +02:00
Gregory Trullemans 27448d5962 Add field into injury form 2023-07-14 10:50:52 +02:00
Gregory Trullemans be886154f8 Add files 2023-07-14 10:46:08 +02:00
Gregory Trullemans bdf3f91bca Interface update 2023-07-14 10:42:53 +02:00
Gregory Trullemans 489045b1bf Add files 2023-07-14 10:30:12 +02:00
Gregory Trullemans 926c5d029f Add Injury and Stability 2023-07-14 10:28:08 +02:00
Gregory Trullemans 03d9873d54 Update template 2023-07-11 11:43:43 +02:00
Gregory Trullemans 87d1fb9193 Update template 2023-07-11 11:42:03 +02:00
Gregory Trullemans 5e47ae48e9 Update template 2023-07-11 11:37:52 +02:00
Gregory Trullemans f38e0934db Move template 2023-07-11 11:34:38 +02:00
Gregory Trullemans 04dcbc7ddb Renaming accident to injury 2023-07-11 11:28:19 +02:00
Gregory Trullemans d66a3f419e Update Injury template 2023-07-11 11:23:29 +02:00
Gregory Trullemans a47df78e40 Update Injury admin 2023-07-11 11:16:01 +02:00
Gregory Trullemans 7b902fb1b6 Add InjuryLocation admin 2023-07-11 11:11:09 +02:00
Gregory Trullemans f28450364c Add field to Injury and add injury location 2023-07-11 11:08:47 +02:00
Gregory Trullemans 770960350b Add field to Injury and add injury location 2023-07-11 11:07:18 +02:00
Gregory Trullemans c539539976 Add field to Injury and add injury location 2023-07-11 11:04:21 +02:00
Gregory Trullemans d226109e28 Rename Accdent to Injury 2023-07-11 10:48:45 +02:00
Gregory Trullemans 49a39980ad Dashboard update 2023-07-10 13:48:40 +02:00
Gregory Trullemans 6d66863638 Bug fix 2023-07-10 13:42:27 +02:00
Gregory Trullemans 32c2fb0f0e Update well being list 2023-07-10 13:40:45 +02:00
Gregory Trullemans 289492d486 Update weel being chart 2023-07-10 13:38:08 +02:00
Gregory Trullemans 62dc8ddcfd Update weel being details 2023-07-10 13:35:48 +02:00
Gregory Trullemans 6951b20b48 Update weel being details 2023-07-10 13:33:33 +02:00
Gregory Trullemans 71244944c4 Update wellbeingform 2023-07-10 11:45:26 +02:00
Gregory Trullemans 8f9ea62bba Update wellbeingform 2023-07-10 11:41:45 +02:00
Gregory Trullemans 798eb911dc Update wellbeingform 2023-07-10 11:14:28 +02:00
Gregory Trullemans b4b63f4a3f Update gymnast details tab 2023-07-10 11:10:05 +02:00
Gregory Trullemans 28a4d75d9b Bug fix 2023-07-10 11:06:00 +02:00
Gregory Trullemans 3053c8ef68 Mind State to WellBeing 2023-07-10 11:04:16 +02:00
38 changed files with 1789 additions and 508 deletions

View File

@ -79,7 +79,7 @@
{% menuitem 'routine_list' 'tim-icons icon-components' 'Routines' %}
{% menuitem 'event_list' 'fal fa-calendar-alt' 'Events' %}
{% if request.user|has_group:"trainer" %}
{% menuitem 'accident_list' 'fal fa-comment-alt-medical' 'Accidents' %}
{% menuitem 'injury_list' 'fal fa-comment-alt-medical' 'Injuries' %}
{% endif %}
{% menuitem 'place_list' 'fal fa-map-marked-alt' 'Places' %}
{% if request.user|has_group:"trainer" %}

View File

@ -1,84 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% load has_group %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
<div class="card">
<div class="card-header">
<h4 class="">{% if accident_id %}Edit{% else %}Add{% endif %} accident</h4>
</div>
<div class="card-body">
<form action="{% if accident_id %}{% url 'accident_update' accident_id %}{% else %}{% url 'accident_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Gymnast <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-9 col-md-9 col-lg-6 col-lg-4 col-xl-4 {% if form.jumper.errors %}has-danger{% endif %}">
{% if request.user|has_group:"trainer" %}
{{ form.gymnast }}
{{ form.gymnast_related }}
{% if form.gymnast.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.gymnast.errors %}{{ error }}{% endfor %}</span>{% endif %}
{% else %}
<input type="text" class="form-control" value="{{ request.user.first_name }} {{ request.user.last_name }}" readonly="readonly" />
<input type="hidden" name="gymnast" id="gymnast" value="{{ request.user.gymnast.id }}" />
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Date <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_skill" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Skill</label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.skill.errors %}has-danger{% endif %}">
{{ form.skill }}
{{ form.skill_related }}
{% if form.skill.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.skill.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_nb_week_off" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label"># Week off</label>
<div class="col-sm-3 col-md-4 col-lg-2 {% if form.nb_week_off.errors %}has-danger{% endif %}">
{{ form.nb_week_off }}
{% if form.nb_week_off.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.nb_week_off.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Informations</label>
<div class="col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_informations.errors %}has-danger{% endif %}">
{{ form.informations }}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if accident_id %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript" >
$(function(){
blackDashboard.initDateTimePicker();
});
const csrf_token = "{{ csrf_token|escapejs }}";
const gymnast_lookup = "{% url 'gymnast_lookup' %}";
const skill_lookup = "{% url 'skill_lookup' %}";
</script>
<script src="{% static "js/template_users/datepicker_maxdate_today.js" %}"></script>
{% if request.session.template == 0 %}
<script src="{% static "js/template_users/gymnast_autocomplete_black.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete_black.js" %}"></script>
{% else %}
<script src="{% static "js/template_users/gymnast_autocomplete.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete.js" %}"></script>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,118 @@
{% extends "base.html" %}
{% load static %}
{% load has_group %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
<div class="card">
<div class="card-header">
<h4 class="">{% if injury_id %}Edit{% else %}Add{% endif %} injury</h4>
</div>
<div class="card-body">
<form action="{% if injury_id %}{% url 'injury_update' injury_id %}{% else %}{% url 'injury_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-3 col-form-label">Gymnast <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.jumper.errors %}has-danger{% endif %}">
{% if request.user|has_group:"trainer" %}
{{ form.gymnast }}
{{ form.gymnast_related }}
{% if form.gymnast.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.gymnast.errors %}{{ error }}{% endfor %}</span>{% endif %}
{% else %}
<input type="text" class="form-control" value="{{ request.user.first_name }} {{ request.user.last_name }}" readonly="readonly" />
<input type="hidden" name="gymnast" id="gymnast" value="{{ request.user.gymnast.id }}" />
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-3 col-form-label">{{ form.date.label }} <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_skill" class="col-4 col-sm-3 col-form-label">Skill</label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.skill.errors %}has-danger{% endif %}">
{{ form.skill }}
{{ form.skill_related }}
{% if form.skill.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.skill.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_injury_type" class="col-4 col-sm-3 col-form-label">{{ form.injury_type.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-8 col-lg-8 col-xl-8 {% if form.injury_type.errors %}has-danger{% endif %}">
{{ form.injury_type }}
{% if form.injury_type.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.injury_type.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_mechanism" class="col-4 col-sm-3 col-form-label">{{ form.mechanism.label }} <span class="text-danger"><b>*</b></span></label>
<div class="col-5 col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.mechanism.errors %}has-danger{% endif %}">
{{ form.mechanism }}
{% if form.mechanism.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.mechanism.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_location" class="col-4 col-sm-3 col-form-label">{{ form.location.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.location.errors %}has-danger{% endif %}">
{{ form.location }}
{% if form.location.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.location.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_body_side" class="col-4 col-sm-3 col-form-label">{{ form.body_side.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-5 col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.body_side.errors %}has-danger{% endif %}">
{{ form.body_side }}
{% if form.body_side.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.body_side.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_diagnosis" class="col-4 col-sm-3 col-form-label">{{ form.diagnosis.label }}</label>
<div class="col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_diagnosis.errors %}has-danger{% endif %}">
{{ form.diagnosis }}
</div>
</div>
<div class="form-group row ">
<label for="id_nb_week_off" class="col-4 col-sm-3 col-form-label"># Week off</label>
<div class="col-sm-3 col-md-4 col-lg-2 {% if form.nb_week_off.errors %}has-danger{% endif %}">
{{ form.nb_week_off }}
{% if form.nb_week_off.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.nb_week_off.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-4 col-sm-3 col-form-label">Informations</label>
<div class="col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_informations.errors %}has-danger{% endif %}">
{{ form.informations }}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if injury_id %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript" >
$(function(){
blackDashboard.initDateTimePicker();
});
const csrf_token = "{{ csrf_token|escapejs }}";
const gymnast_lookup = "{% url 'gymnast_lookup' %}";
const skill_lookup = "{% url 'skill_lookup' %}";
</script>
<script src="{% static "js/template_users/datepicker_maxdate_today.js" %}"></script>
{% if request.session.template == 0 %}
<script src="{% static "js/template_users/gymnast_autocomplete_black.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete_black.js" %}"></script>
{% else %}
<script src="{% static "js/template_users/gymnast_autocomplete.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete.js" %}"></script>
{% endif %}
{% endblock %}

View File

@ -6,19 +6,20 @@
<div class="col-12 col-sm-8 col-md-6">
<div class="card">
<div class="card-header">
<h4 class="mb-0">Accident : {{ accident.date | date:"d-m-Y" }}</h4>
<h4 class="mb-0">Injury on {{ injury.date | date:"j N Y" }}</h4>
</div>
<div class="card-body">
<a href="{% url 'gymnast_details' accident.gymnast.id %}">{{ accident.gymnast }}</a><br />
{% if accident.nb_week_off %}
{{ accident.nb_week_off }} week(s) off.<br />
<a href="{% url 'gymnast_details' injury.gymnast.id %}">{{ injury.gymnast }}</a>{% if injury.skill %} injuried on <i>{{ injury.skill.notation }}</i>{% endif %}<br />
{{ injury.get_mechanism_display }} on {{ injury.location}} ({{ injury.get_body_side_display }})<br />
{% if injury.nb_week_off %}
Gymnast {{ injury.nb_week_off }} week(s) off.<br />
{% endif %}
<br />
{{ accident.to_markdown | safe }}
{{ injury.to_markdown | safe }}
<div class="card-footer pl-0 pb-0">
<a href="{% url 'accident_list' %}">
<a href="{% url 'injuries_list' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="tim-icons icon-double-left"></i>
</button>

View File

@ -5,11 +5,11 @@
<div class="card-header">
<div class="row">
<div class="col-md-4">
<h4 class=""> Accidents Listing</h4>
<h4 class=""> Injuries Listing</h4>
</div>
<div class="col-1 ml-auto">
<div class="text-right">
<a href="{% url 'accident_create' %}">
<a href="{% url 'injury_create' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
@ -20,37 +20,43 @@
</div>
<div class="card-body">
<div class="table-responsive">
{% if accident_list %}
<table class="table tablesorter table-striped" data-sort="table" id="accident_table">
{% if injuries_list %}
<table class="table tablesorter table-striped" data-sort="table" id="injury_table">
<thead class="text-primary">
<tr>
<th style="width: 3%"></th>
<th class="header text-left" style="width: 10%">Date</th>
<th class="header text-left" style="width: 30%">Gymnast</th>
<th style="width: 30%">Skill</th>
<th style="width: 25%"># Week off</th>
<th class="header text-left" style="width: 8%">Date</th>
<th class="header text-left" style="width: 20%">Gymnast</th>
<th class="header text-left" style="width: 9%">Mechanism</th>
<th class="header text-left" style="width: 20%">Location</th>
<th class="header text-left" style="width: 8%">Side</th>
<th style="width: 12%">Skill</th>
<th style="width: 8%"># Week off</th>
</tr>
</thead>
<tbody>
{% for accident in accident_list %}
{% for injury in injuries_list %}
<tr role="row" class="{% cycle 'odd' 'even' %}">
<td>
<a href="{% url 'accident_update' accident.id %}">
<a href="{% url 'injury_update' injury.id %}">
<span class="tim-icons icon-pencil text-warning"></span>
</a>
</td>
<td class="text-left"><a href="{% url 'accident_details' accident.id %}">{{ accident.date | date:"d-m-Y" }}</a></td>
<td class="text-left"><a href="{% url 'gymnast_details_tab' accident.gymnast.id 'physiological' %}">{{ accident.gymnast }}</a></td>
<td class="text-left"><a href="{% url 'injury_details' injury.id %}">{{ injury.date | date:"d-m-Y" }}</a></td>
<td class="text-left"><a href="{% url 'gymnast_details_tab' injury.gymnast.id 'physiological' %}">{{ injury.gymnast }}</a></td>
<td class="text-left">{{ injury.get_mechanism_display }}</td>
<td class="text-left">{{ injury.location }}</td>
<td class="text-left">{{ injury.get_body_side_display }}</td>
<td class="text-left">
{% if accident.skill %}
<a href="{% url 'skill_details' accident.skill.id %}">{{ accident.skill }}</a>
{% if injury.skill %}
<a href="{% url 'skill_details' injury.skill.id %}">{{ injury.skill.notation }}</a>
{% else %}
-
{% endif %}
</td>
<td class="text-right">
{% if accident.nb_week_off %}
{{ accident.nb_week_off }}
{% if injury.nb_week_off %}
{{ injury.nb_week_off }}
{% else %}
-
{% endif %}
@ -60,7 +66,7 @@
</tbody>
</table>
{% else %}
<p class="muted-text">There are no accident corresponding to your criterias.</p>
<p class="muted-text">There are no injury corresponding to your criterias.</p>
{% endif %}
</div>
</div>
@ -70,7 +76,7 @@
{% block footerscript %}
<script type="text/javascript">
$(document).ready(function () {
$('#accident_table').tablesorter({
$('#injury_table').tablesorter({
headers: {
0: { sorter: false }, // disable first column
},
@ -78,7 +84,7 @@
sortList: [[1, 1]]
});
$('#accident_table').DataTable({
$('#injury_table').DataTable({
scrollY: 500,
paging: false,
searching: false,

View File

@ -1,92 +0,0 @@
{% extends "base.html" %}
{% load static %}
{% load has_group %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-8 col-lg-6 col-xl-6">
<div class="card">
<div class="card-header">
<h4 class="">{% if mindstate_id %}Edit{% else %}Add{% endif %} mind state score</h4>
</div>
<div class="card-body">
<form action="{% if mindstate_id %}{% url 'mindstate_update' mindstate_id %}{% else %}{% url 'mindstate_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-sm-2 col-md-3 col-lg-3 col-xl-2 col-form-label">Gymnast <span class="text-danger"><b>*</b></span></label>
<div class="col-8 col-md-9 col-lg-6 col-lg-8 col-xl-8 {% if form.jumper.errors %}has-danger{% endif %}">
{% if request.user|has_group:"trainer" %}
{{ form.gymnast }}
{{ form.gymnast_related }}
{% if form.gymnast.errors %}
<label class="text-danger" for="id_gymnast" id="gymnast-error">
{% for error in form.gymnast.errors %}{{ error }}{% endfor %}
</label>
{% endif %}
{% else %}
<input type="text" class="form-control" value="{{ request.user.first_name }} {{ request.user.last_name }}" readonly="readonly" />
<input type="hidden" name="gymnast" id="gymnast" value="{{ request.user.gymnast.id }}" />
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-sm-2 col-md-3 col-lg-3 col-xl-2 col-form-label">Date <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-3 col-lg-4 col-xl-3 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_event" class="col-sm-2 col-md-3 col-lg-3 col-xl-2 col-form-label">Event</label>
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-10 {% if form.date.errors %}has-danger{% endif %}">
{{ form.event }}
{{ form.event_related }}
{% if form.eventt.errors %}
<label class="text-danger" for="id_eventt" id="event-error">
{% for error in form.event.errors %}{{ error }}{% endfor %}
</label>
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_score" class="col-sm-2 col-md-3 col-lg-3 col-xl-2 col-form-label">Score <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-3 col-lg-3 {% if form.score.errors %}has-danger{% endif %}">
{{ form.score }}
{% if form.score.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.score.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Informations</label>
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_information.errors %}has-danger{% endif %}">
{{ form.informations }}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if mindstate_id %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript" >
$(function(){
blackDashboard.initDateTimePicker();
});
const csrf_token = "{{ csrf_token|escapejs }}";
const gymnast_lookup = "{% url 'gymnast_lookup' %}";
const event_lookup = "{% url 'event_lookup' %}";
</script>
<script src="{% static "js/template_users/datepicker_maxdate_today.js" %}"></script>
{% if request.session.template == 0 %}
<script src="{% static "js/template_users/gymnast_autocomplete_black.js" %}"></script>
<script src="{% static "js/template_users/event_autocomplete_black.js" %}"></script>
{% else %}
<script src="{% static "js/template_users/gymnast_autocomplete.js" %}"></script>
<script src="{% static "js/template_users/event_autocomplete.js" %}"></script>
{% endif %}
{% endblock %}

View File

@ -1,30 +0,0 @@
{% extends "base.html" %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-8 col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title mb-0">Mind State {{ mindstate.date | date:"d N Y" }}</h4>
</div>
<div class="card-body">
<a href="{% url 'gymnast_details_tab' mindstate.gymnast.id 'physiological' %}">{{ mindstate.gymnast }}</a> : {{ mindstate.score }}
<br />
<br />
{{ mindstate.to_markdown | safe }}
<div class="card-footer pl-0 pb-0">
<a href="{% url 'mindstate_list' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="tim-icons icon-double-left"></i>
</button>
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -54,6 +54,20 @@
{% if form.number_of_hours_per_week.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.number_of_hours_per_week.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_number_of_s_and_c_sessions_per_week" class="col-sm-3 col-md-3 col-lg-3 col-xl-3 col-form-label">S&C Training/week</label>
<div class="col-sm-3 col-md-3 col-lg-2 {% if form.number_of_s_and_c_sessions_per_week.errors %}has-danger{% endif %}">
{{ form.number_of_s_and_c_sessions_per_week }}
{% if form.number_of_s_and_c_sessions_per_week.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.number_of_s_and_c_sessions_per_week.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_number_of_s_and_c_hours_per_week" class="col-sm-3 col-md-3 col-lg-3 col-xl-3 col-form-label">S&C Hours/week</label>
<div class="col-sm-3 col-md-3 col-lg-2 {% if form.numbernumber_of_s_and_c_hours_per_week_of_hours_per_week.errors %}has-danger{% endif %}">
{{ form.number_of_s_and_c_hours_per_week }}
{% if form.number_of_s_and_c_hours_per_week.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.number_of_s_and_c_hours_per_week.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_category" class="col-sm-3 col-md-3 col-lg-3 col-xl-3 col-form-label">Category <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-3 col-lg-3 {% if form.category.errors %}has-danger{% endif %}">

View File

@ -29,8 +29,10 @@
<th></th>
<th class="header text-left">Gymnast</th>
<th class="header text-left">Season</th>
<th class="header text-left"># training/week</th>
<th class="header text-left"># hours/week</th>
<th class="header text-left"># training/w</th>
<th class="header text-left"># hours/w</th>
<th class="header text-left"># S&C training/w</th>
<th class="header text-left"># S&C hours/w</th>
<th class="header text-left">category</th>
<th class="header text-center">club</th>
</tr>
@ -47,6 +49,8 @@
<td>{{ season_information.season }}</td>
<td>{{ season_information.number_of_training_sessions_per_week }}</td>
<td>{{ season_information.number_of_hours_per_week }}</td>
<td>{{ season_information.number_of_s_and_c_sessions_per_week }}</td>
<td>{{ season_information.number_of_s_and_c_hours_per_week }}</td>
<td class="text-right">{{ season_information.get_category_display }}</td>
<td class="text-right">{{ season_information.club.name }}</td>
</tr>

View File

@ -0,0 +1,118 @@
{% extends "base.html" %}
{% load static %}
{% load has_group %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-8 col-lg-8 col-xl-6">
<div class="card">
<div class="card-header">
<h4 class="">{% if injury_id %}Edit{% else %}Add{% endif %} injury</h4>
</div>
<div class="card-body">
<form action="{% if injury_id %}{% url 'injury_update' injury_id %}{% else %}{% url 'injury_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-3 col-form-label">Gymnast <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.jumper.errors %}has-danger{% endif %}">
{% if request.user|has_group:"trainer" %}
{{ form.gymnast }}
{{ form.gymnast_related }}
{% if form.gymnast.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.gymnast.errors %}{{ error }}{% endfor %}</span>{% endif %}
{% else %}
<input type="text" class="form-control" value="{{ request.user.first_name }} {{ request.user.last_name }}" readonly="readonly" />
<input type="hidden" name="gymnast" id="gymnast" value="{{ request.user.gymnast.id }}" />
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-3 col-form-label">{{ form.date.label }} <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_skill" class="col-4 col-sm-3 col-form-label">Skill</label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.skill.errors %}has-danger{% endif %}">
{{ form.skill }}
{{ form.skill_related }}
{% if form.skill.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.skill.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_injury_type" class="col-4 col-sm-3 col-form-label">{{ form.injury_type.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-8 col-lg-8 col-xl-8 {% if form.injury_type.errors %}has-danger{% endif %}">
{{ form.injury_type }}
{% if form.injury_type.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.injury_type.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_mechanism" class="col-4 col-sm-3 col-form-label">{{ form.mechanism.label }} <span class="text-danger"><b>*</b></span></label>
<div class="col-5 col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.mechanism.errors %}has-danger{% endif %}">
{{ form.mechanism }}
{% if form.mechanism.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.mechanism.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_location" class="col-4 col-sm-3 col-form-label">{{ form.location.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-sm-8 col-md-6 col-lg-6 col-xl-6 {% if form.location.errors %}has-danger{% endif %}">
{{ form.location }}
{% if form.location.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.location.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_body_side" class="col-4 col-sm-3 col-form-label">{{ form.body_side.label }}<span class="text-danger"><b>*</b></span></label>
<div class="col-5 col-sm-3 col-md-4 col-lg-4 col-xl-4 {% if form.body_side.errors %}has-danger{% endif %}">
{{ form.body_side }}
{% if form.body_side.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.body_side.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_diagnosis" class="col-4 col-sm-3 col-form-label">{{ form.diagnosis.label }}</label>
<div class="col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_diagnosis.errors %}has-danger{% endif %}">
{{ form.diagnosis }}
</div>
</div>
<div class="form-group row ">
<label for="id_nb_week_off" class="col-4 col-sm-3 col-form-label"># Week off</label>
<div class="col-sm-3 col-md-4 col-lg-2 {% if form.nb_week_off.errors %}has-danger{% endif %}">
{{ form.nb_week_off }}
{% if form.nb_week_off.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.nb_week_off.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-4 col-sm-3 col-form-label">Informations</label>
<div class="col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_informations.errors %}has-danger{% endif %}">
{{ form.informations }}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if injury_id %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript" >
$(function(){
blackDashboard.initDateTimePicker();
});
const csrf_token = "{{ csrf_token|escapejs }}";
const gymnast_lookup = "{% url 'gymnast_lookup' %}";
const skill_lookup = "{% url 'skill_lookup' %}";
</script>
<script src="{% static "js/template_users/datepicker_maxdate_today.js" %}"></script>
{% if request.session.template == 0 %}
<script src="{% static "js/template_users/gymnast_autocomplete_black.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete_black.js" %}"></script>
{% else %}
<script src="{% static "js/template_users/gymnast_autocomplete.js" %}"></script>
<script src="{% static "js/template_users/skill_autocomplete.js" %}"></script>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,59 @@
{% extends "base.html" %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-8 col-md-6">
<div class="card">
<div class="card-header">
<h4 class="mb-0">Stability on {{ stability.date | date:"j N Y" }}</h4>
<a href="{% url 'gymnast_details_tab' stability.gymnast.id 'physiological' %}">{{ stability.gymnast }}</a>
</div>
<div class="card-body">
<table class="table table-striped">
<tr>
<td>Anterior chain</td>
<td>{{ stability.anterior_chain }}</td>
</tr>
<tr>
<td>Posterior chain left</td>
<td>{{ stability.posterior_chain_left }}</td>
</tr>
<tr>
<td>Posterior chain right</td>
<td>{{ stability.posterior_chain_right }}</td>
</tr>
<tr>
<td>Leg lowering</td>
<td>{{ stability.leg_lowering }}</td>
</tr>
<tr>
<td>SL bridge</td>
<td>
{% for sl_bridge in stability_sl_bridge %}
{{ sl_bridge }}
{% endfor %}
</td>
</tr>
<tr>
<td>Side plank leg raise</td>
<td>
{% for side_plank_leg_raise in stability_side_plank_leg_raise %}
{{ side_plank_leg_raise }}
{% endfor %}
</td>
</tr>
</table>
<div class="card-footer pl-0 pb-0">
<a href="{% url 'stability_list' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="tim-icons icon-double-left"></i>
</button>
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,86 @@
{% extends "listing.html" %}
{% block datacontent %}
<div class="card mb-0">
<div class="card-header">
<div class="row">
<div class="col-md-4">
<h4 class=""> Stabilities Listing</h4>
</div>
<div class="col-1 ml-auto">
<div class="text-right">
<a href="{% url 'injury_create' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
</a>
</div>
</div>
</div>
</div>
<div class="card-body">
<div class="table-responsive">
{% if stabilities_list %}
<table class="table tablesorter table-striped" data-sort="table" id="stability_table">
<thead class="text-primary">
<tr>
<th style="width: 3%"></th>
<th class="header text-left" style="width: 8%">Date</th>
<th class="header text-left" style="width: 20%">Gymnast</th>
<th class="header text-left">Ant. chain</th>
<th class="header text-left">Post. chain L</th>
<th class="header text-left">Post. chain R</th>
<th class="header text-left">leg_lowering</th>
<!-- <th class="header text-left">sl_bridge</th>
<th class="header text-left">side_plank_leg_raise</th> -->
</tr>
</thead>
<tbody>
{% for stability in stabilities_list %}
<tr role="row" class="{% cycle 'odd' 'even' %}">
<td>
<a href="{% url 'injury_update' stability.id %}">
<span class="tim-icons icon-pencil text-warning"></span>
</a>
</td>
<td class="text-left"><a href="{% url 'stability_details' stability.id %}">{{ stability.date | date:"d-m-Y" }}</a></td>
<td class="text-left"><a href="{% url 'gymnast_details_tab' stability.gymnast.id 'physiological' %}">{{ stability.gymnast }}</a></td>
<td class="text-left">{{ stability.anterior_chain }}</td>
<td class="text-left">{{ stability.posterior_chain_left }}</td>
<td class="text-left">{{ stability.posterior_chain_right }}</td>
<td class="text-left">{{ stability.leg_lowering }}</td>
<!-- <td class="text-right">{{ stability.sl_bridge }}</td>
<td class="text-right">{{ stability.side_plank_leg_raise }}</td> -->
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="muted-text">There are no injury corresponding to your criterias.</p>
{% endif %}
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript">
$(document).ready(function () {
$('#stability_table').tablesorter({
headers: {
0: { sorter: false }, // disable first column
},
dateFormat: "uk",
sortList: [[1, 1]]
});
$('#stability_table').DataTable({
scrollY: 500,
paging: false,
searching: false,
ordering: false,
"bInfo": false,
});
});
</script>
{% endblock %}

View File

@ -0,0 +1,134 @@
{% extends "base.html" %}
{% load static %}
{% load has_group %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-12 col-md-8 col-lg-6 col-xl-6">
<div class="card">
<div class="card-header">
<h4 class="">{% if wellbeing_id %}Edit{% else %}Add{% endif %} mind state score</h4>
</div>
<div class="card-body">
<form action="{% if wellbeing_id %}{% url 'wellbeing_update' wellbeing_id %}{% else %}{% url 'wellbeing_create' %}{% endif %}" method="post" class="form-horizontal" id="formulaire" name="formulaire">
{% csrf_token %}
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Gymnast <span class="text-danger"><b>*</b></span></label>
<div class="col-8 col-md-9 col-lg-6 col-lg-8 col-xl-8 {% if form.jumper.errors %}has-danger{% endif %}">
{% if request.user|has_group:"trainer" %}
{{ form.gymnast }}
{{ form.gymnast_related }}
{% if form.gymnast.errors %}
<label class="text-danger" for="id_gymnast" id="gymnast-error">
{% for error in form.gymnast.errors %}{{ error }}{% endfor %}
</label>
{% endif %}
{% else %}
<input type="text" class="form-control" value="{{ request.user.first_name }} {{ request.user.last_name }}" readonly="readonly" />
<input type="hidden" name="gymnast" id="gymnast" value="{{ request.user.gymnast.id }}" />
{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_date" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Date <span class="text-danger"><b>*</b></span></label>
<div class="col-sm-3 col-md-3 col-lg-4 col-xl-3 {% if form.date.errors %}has-danger{% endif %}">
{{ form.date }}
{% if form.date.errors %}<span class="btn btn-sm btn-danger-outline">{% for error in form.date.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
</div>
<div class="form-group row ">
<label for="id_event" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Event</label>
<div class="col-8 col-sm-8 col-md-8 col-lg-8 col-xl-9 {% if form.date.errors %}has-danger{% endif %}">
{{ form.event }}
{{ form.event_related }}
{% if form.eventt.errors %}
<label class="text-danger" for="id_eventt" id="event-error">
{% for error in form.event.errors %}{{ error }}{% endfor %}
</label>
{% endif %}
</div>
</div><div class="form-group row ">
<label for="id_mindstate" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">{{ form.mind_state.label }} <span class="text-danger"><b>*</b></span></label>
<div class="col-4 col-sm-3 col-md-3 col-lg-3 {% if form.mindstate.errors %}has-danger{% endif %}">
{{ form.mind_state }}
{% if form.mind_state.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.mind_state.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
<div class="col-4 col-sm-3 col-md-5 c ol-lg-5">
<h3 class="card-category text-muted">(1: Very Bad - 10: Very Good)</h3>
</div>
</div>
<div class="form-group row ">
<label for="id_sleep" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Sleep <span class="text-danger"><b>*</b></span></label>
<div class="col-4 col-sm-3 col-md-3 col-lg-3 {% if form.sleep.errors %}has-danger{% endif %}">
{{ form.sleep }}
{% if form.sleep.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.sleep.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
<div class="col-4 col-sm-3 col-md-5 col-lg-5">
<h3 class="card-category text-muted">(1: Very Bad - 10: Very Good)</h3>
</div>
</div>
<div class="form-group row ">
<label for="id_stress" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Stress <span class="text-danger"><b>*</b></span></label>
<div class="col-4 col-sm-3 col-md-3 col-lg-3 {% if form.stress.errors %}has-danger{% endif %}">
{{ form.stress }}
{% if form.stress.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.stress.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
<div class="col-4 col-sm-3 col-md-5 col-lg-5">
<h3 class="card-category text-muted">(1: Very Low - 10: Very High)</h3>
</div>
</div>
<div class="form-group row ">
<label for="id_fatigue" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Fatigue <span class="text-danger"><b>*</b></span></label>
<div class="col-4 col-sm-3 col-md-3 col-lg-3 {% if form.fatigue.errors %}has-danger{% endif %}">
{{ form.fatigue }}
{% if form.fatigue.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.fatigue.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
<div class="col-4 col-sm-3 col-md-5 col-lg-5">
<h3 class="card-category text-muted">(1: Very Low - 10: Very High)</h3>
</div>
</div>
<div class="form-group row ">
<label for="id_muscle_soreness" class="col-4 col-sm-2 col-md-4 col-lg-4 col-xl-3 col-form-label">Muscle Soreness <span class="text-danger"><b>*</b></span></label>
<div class="col-4 col-sm-3 col-md-3 col-lg-3 {% if form.muscle_soreness.errors %}has-danger{% endif %}">
{{ form.muscle_soreness }}
{% if form.muscle_soreness.errors %}&nbsp;<span class="btn btn-sm btn-danger-outline">{% for error in form.muscle_soreness.errors %}{{ error }}{% endfor %}</span>{% endif %}
</div>
<div class="col-4 col-sm-3 col-md-5 col-lg-5">
<h3 class="card-category text-muted">(1: Very Low - 10: Very High)</h3>
</div>
</div>
<div class="form-group row ">
<label for="id_information" class="col-sm-2 col-md-2 col-lg-2 col-xl-2 col-form-label">Informations</label>
<div class="col-8 col-sm-9 col-md-9 col-lg-9 col-xl-9 {% if form.id_information.errors %}has-danger{% endif %}">
{{ form.informations }}
</div>
</div>
<div class="form-group text-center">
<input type="submit" value="{% if wellbeing_id %}Save{% else %}Add{% endif %}" class="btn btn-warning" />
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block footerscript %}
<script type="text/javascript" >
$(function(){
blackDashboard.initDateTimePicker();
});
const csrf_token = "{{ csrf_token|escapejs }}";
const gymnast_lookup = "{% url 'gymnast_lookup' %}";
const event_lookup = "{% url 'event_lookup' %}";
</script>
<script src="{% static "js/template_users/datepicker_maxdate_today.js" %}"></script>
{% if request.session.template == 0 %}
<script src="{% static "js/template_users/gymnast_autocomplete_black.js" %}"></script>
<script src="{% static "js/template_users/event_autocomplete_black.js" %}"></script>
{% else %}
<script src="{% static "js/template_users/gymnast_autocomplete.js" %}"></script>
<script src="{% static "js/template_users/event_autocomplete.js" %}"></script>
{% endif %}
{% endblock %}

View File

@ -0,0 +1,37 @@
{% extends "base.html" %}
{% block content %}
<div class="row justify-content-center">
<div class="col-12 col-sm-8 col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title mb-0">Well being {{ wellbeing.date | date:"d N Y" }}</h4>
</div>
<div class="card-body">
<a href="{% url 'gymnast_details_tab' wellbeing.gymnast.id 'physiological' %}">{{ wellbeing.gymnast }}</a><br />
Mindstate : {{ wellbeing.mindstate }}<br />
Sleep : {{ wellbeing.sleep }}<br />
Stress : {{ wellbeing.stress }}<br />
Fatigue : {{ wellbeing.fatigue }}<br />
Muscle soreness : {{ wellbeing.muscle_soreness }}<br />
<br />
{% if wellbeing.to_markdown %}
{{ wellbeing.to_markdown | safe }}
{% else %}
<p class="text-muted">No additionnal details.</p>
{% endif %}
<div class="card-footer pl-0 pb-0">
<a href="{% url 'wellbeing_list' %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="tim-icons icon-double-left"></i>
</button>
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -7,12 +7,12 @@
<div class="card">
<div class="card-header row">
<div class="col-8">
<h4 class="">Mind State list {% if gymnast %}for <a href="{% url 'gymnast_details_tab' gymnast.id 'physiological' %}"><i>{{ gymnast }}</i></a>{% endif %}</h4>
<h4 class="">Well being list {% if gymnast %}for <a href="{% url 'gymnast_details_tab' gymnast.id 'physiological' %}"><i>{{ gymnast }}</i></a>{% endif %}</h4>
</div>
<div class="col-1 ml-auto">
<div class="text-right">
{% if request.user|has_group:"trainer" %}
<a href="{% url 'mindstate_create_for_gymnast' gymnast.id %}">
<a href="{% if gymnast %}{% url 'wellbeing_create_for_gymnast' gymnast.id %}{% else %}{% url 'wellbeing_create' %}{% endif %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
@ -22,33 +22,41 @@
</div>
</div>
<div class="card-body">
{% if mindstate_list %}
{% if wellbeing_list %}
<table class="table tablesorter table-striped mb-0" data-sort="table" id="mindstate_table">
<thead>
<tr>
<th></th>
<th class="header text-left">Date</th>
<th class="header text-left">Gymnast</th>
<th class="header text-left">Score</th>
<th class="header text-center">Mindstate</th>
<th class="header text-center">Sleep</th>
<th class="header text-center">Stress</th>
<th class="header text-center">Fatigue</th>
<th class="header text-center">Muscle soreness</th>
</tr>
</thead>
<tbody>
{% for state in mindstate_list %}
{% for wellbeing in wellbeing_list %}
<tr>
<td>
<a href="{% url 'mindstate_update' state.id %}">
<a href="{% url 'wellbeing_update' wellbeing.id %}">
<span class="tim-icons icon-pencil text-warning"></span>
</a>
</td>
<td class="text-left">{{ state.date | date:"d-m-Y" }}</td>
<td class="text-left"><a href="{% url 'gymnast_details_tab' state.gymnast.id 'physiological' %}">{{ state.gymnast }}</a></td>
<td>{{ state.score }}</td>
<td class="text-left"><a href="{% url 'wellbeing_details' wellbeing.id %}">{{ wellbeing.date | date:"d-m-Y" }}</a></td>
<td class="text-left"><a href="{% url 'gymnast_details_tab' wellbeing.gymnast.id 'physiological' %}">{{ wellbeing.gymnast }}</a></td>
<td class="text-right">{{ wellbeing.mind_state }}</td>
<td class="text-right">{{ wellbeing.sleep }}</td>
<td class="text-right">{{ wellbeing.stress }}</td>
<td class="text-right">{{ wellbeing.fatigue }}</td>
<td class="text-right">{{ wellbeing.muscle_soreness }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="text-muted">There are no mindstates corresponding to your criterias</p>
<p class="text-muted">There are no well being corresponding to your criterias</p>
{% endif %}
</div>
</div>

View File

@ -2,10 +2,10 @@
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Accidents</h4>
<h4>Injuries</h4>
</div>
<div class="card-body pt-0 pb-0">
{% if accident_list %}
{% if injury_list %}
<div class="card-body pl-0 pt-0 pr-0">
<table class="table table-striped table-condensed tablesorter mb-1">
<thead>
@ -16,14 +16,14 @@
</tr>
</thead>
<tbody>
{% for accident in accident_list %}
{% for accident in injury_list %}
<tr>
<td class="text-left">
<a href="{% url 'accident_update' accident.id %}">
<a href="{% url 'injury_update' accident.id %}">
&nbsp;<span class="tim-icons icon-pencil text-warning"></span>
</a>
</td>
<td class="text-center"><a href="{% url 'accident_details' accident.id %}">{{ accident.date | date:"d-m-Y" }}</a></td>
<td class="text-center"><a href="{% url 'injury_details' accident.id %}">{{ accident.date | date:"d-m-Y" }}</a></td>
<td class="text-left"><a href="{% url 'skill_details' accident.skill.id %}">{{ accident.skill }}</a></td>
</tr>
{% endfor %}
@ -35,7 +35,7 @@
{% endif %}
</div>
<div class="card-footer text-right text-muted pt-0">
<a href="{% url 'accident_create_for_gymnast' gymnastid %}">
<a href="{% url 'injury_create_for_gymnast' gymnastid %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>

View File

@ -8,14 +8,14 @@
<h4>Mindstates</h4>
</div>
<div class="card-body pt-0 pb-0">
{% if mindstate_list %}
{% if wellbeing_list %}
<div>
<canvas id="chartjs_mindstate" class="chartjs" width="400" height="200"></canvas>
<canvas id="chartjs_wellbeing" class="chartjs" width="400" height="200"></canvas>
</div>
<div class="row">
<div class="col-md-8 col-l-6 col-xl-4 offset-xl-4">
<table class="table tablesorter table-striped table-condensed" id="mindstate_table">
<table class="table tablesorter table-striped table-condensed" id="wellbeing_table">
<thead>
<tr>
<th style="width: 4%"></th>
@ -24,7 +24,7 @@
</tr>
</thead>
<tbody>
{% for state in mindstate_list %}
{% for state in wellbeing_list %}
<tr class="routine_{{ score.routine_type }}">
<td>
<a href="{% url 'score_update' state.id %}">
@ -43,7 +43,7 @@
</div>
<script type="text/javascript">
$(document).ready(function () {
$('#mindstate_table').tablesorter({
$('#wellbeing_table').tablesorter({
headers: {
0: { sorter: false },
},
@ -54,12 +54,12 @@
});
</script>
{% else %}
<p class="text-muted">No mindstate recorded for this gymnast.</p>
<p class="text-muted">No wellbeing recorded for this gymnast.</p>
{% endif %}
</div>
<div class="card-footer text-right text-muted pt-0">
{% if request.user|has_group:"trainer" or request.user|is_user_equal_to_gymnast:gymnastid %}
<a href="{% url 'mindstate_create_for_gymnast' gymnastid %}">
<a href="{% url 'wellbeing_create_for_gymnast' gymnastid %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
@ -71,18 +71,18 @@
</div>
<script type="text/javascript">
new Chart(document.getElementById("chartjs_mindstate"), {
new Chart(document.getElementById("chartjs_wellbeing"), {
type: 'line',
data: {
datasets: [
{% if mindstate_list %}
{% if wellbeing_list %}
{
label: 'Mindstate',
backgroundColor: 'rgb(255, 99, 132, 0.25)',
borderColor: 'rgb(255, 99, 132)',
fill: true,
data: [
{% for state in mindstate_list %}
{% for state in wellbeing_list %}
{
x: '{{ state.date | date:"d-m-Y" }}',
y: '{{ state.score }}'

View File

@ -53,13 +53,13 @@
{% endif %}
</div>
<div class="col-4">
{% if last_mindstate or last_height_weigth or mindstate_analyse or height_analyse or weight_analyse %}
{% if last_wellbeing or last_height_weigth or wellbeing_analyse or height_analyse or weight_analyse %}
<h4>Physiological</h4>
<table class="table">
<tr>
<td class="pt-0 pb-0">Mind state</td>
<td class="pt-0 pb-0">{{ last_mindstate.score }}</td>
<td class="pt-0 pb-0">{{ mindstate_analyse }}</td>
<td class="pt-0 pb-0">{{ last_wellbeing.score }}</td>
<td class="pt-0 pb-0">{{ wellbeing_analyse }}</td>
</tr>
<tr>
<td class="pt-0 pb-0">Height</td>

View File

@ -53,14 +53,14 @@
{% endif %}
</div>
<div class="col-4">
{% if last_mindstate or last_height_weigth or mindstate_analyse or height_analyse or weight_analyse %}
{% if last_wellbeing or last_height_weigth or wellbeing_analyse or height_analyse or weight_analyse %}
<h4>Physiological</h4>
<table class="table">
{% if last_mindstate %}
{% if last_wellbeing %}
<tr>
<td class="pt-0 pb-0">Mind state</td>
<td class="pt-0 pb-0">{{ last_mindstate }}</td>
<td class="pt-0 pb-0">{% if mindstate_analyse %}{{ mindstate_analyse }}{% endif %}</td>
<td class="pt-0 pb-0">{{ last_wellbeing }}</td>
<td class="pt-0 pb-0">{% if wellbeing_analyse %}{{ wellbeing_analyse }}{% endif %}</td>
</tr>
{% endif %}
{% if last_height and last_weight %}

View File

@ -2,7 +2,7 @@
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h4>Height/Weight</h4>
<h4>Height & Weight</h4>
</div>
<div class="card-body pt-0 pb-0 pr-0 pl-0">
{% if height_weight_list %}
@ -34,27 +34,27 @@
<div class="col-md-6">
<div class="card mb-4">
<div class="card-header">
<h4>Mindstates</h4>
<h4>Well Being</h4>
</div>
<div class="card-body pt-0 pb-0 pr-0 pl-0">
{% if mindstate_list %}
{% if wellbeing_list %}
<div>
<canvas id="chart_mindstate" class="chartjs" width="400" height="200"></canvas>
<canvas id="chart_wellbeing" class="chartjs" width="400" height="200"></canvas>
</div>
{% else %}
<p class="pl-3 text-muted">No mindstate recorded for this gymnast.</p>
<p class="pl-3 text-muted">No wellbeing recorded for this gymnast.</p>
{% endif %}
</div>
<div class="card-footer text-right text-muted pt-0">
{% if mindstate_list %}
<a href="{% url 'mindstate_list_for_gymnast' gymnast_id %}">
{% if wellbeing_list %}
<a href="{% url 'wellbeing_list_for_gymnast' gymnast_id %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fal fa-file-medical-alt"></i>
</button>
</a>
{% endif %}
<a href="{% url 'mindstate_create_for_gymnast' gymnast_id %}">
<a href="{% url 'wellbeing_create_for_gymnast' gymnast_id %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
@ -67,40 +67,46 @@
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4>Accidents</h4>
<h4>Injuries</h4>
</div>
<div class="card-body pt-0 pb-0">
{% if accident_list %}
<table class="table tablesorter table-striped table-condensed" id="accident_table">
{% if injuries_list %}
<table class="table tablesorter table-striped table-condensed" id="injury_table">
<thead>
<tr>
<th style="width: 3%"></th>
<th class="header text-center" style="width: 10%">Date</th>
<th class="header text-left" style="width: 50%">Skill</th>
<th class="header text-left" style="width: 40%"># Week Off</th>
<th class="header text-left" style="width: 10%">Mechanism</th>
<th class="header text-left" style="width: 25%">Location</th>
<th class="header text-left" style="width: 10%">Side</th>
<th class="header text-left" style="width: 15%">Skill</th>
<th class="header text-center" style="width: 10%"># Week Off</th>
</tr>
</thead>
<tbody>
{% for accident in accident_list %}
{% for injury in injuries_list %}
<tr>
<td class="text-left">
<a href="{% url 'accident_update' accident.id %}">
<a href="{% url 'injury_update' injury.id %}">
&nbsp;<span class="tim-icons icon-pencil text-warning"></span>
</a>
</td>
<td class="text-center"><a href="{% url 'accident_details' accident.id %}">{{ accident.date | date:"d-m-Y" }}</a></td>
<td class="text-left">{% if accident.skill %}<a href="{% url 'skill_details' accident.skill.id %}">{{ accident.skill }}</a>{% else %}-{% endif %}</td>
<td class="text-left">{{ accident.nb_week_off }}</td>
<td class="text-center"><a href="{% url 'injury_details' injury.id %}">{{ injury.date | date:"d-m-Y" }}</a></td>
<td class="text-left">{{ injury.get_mechanism_display }}</td>
<td class="text-left">{{ injury.location }}</td>
<td class="text-left">{{ injury.get_body_side_display }}</td>
<td class="text-left">{% if injury.skill %}<a href="{% url 'skill_details' injury.skill.id %}">{{ injury.skill.notation }}</a>{% else %}-{% endif %}</td>
<td class="text-center">{{ injury.nb_week_off }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="text-muted">No accident known for this gymnast.</p>
<p class="text-muted">No injury known for this gymnast.</p>
{% endif %}
</div>
<div class="card-footer text-right text-muted pt-0">
<a href="{% url 'accident_create_for_gymnast' gymnast_id %}">
<a href="{% url 'injury_create_for_gymnast' gymnast_id %}">
<button type="submit" value="add" class="btn btn-icon btn-warning ">
<i class="fas fa-plus"></i>
</button>
@ -204,41 +210,142 @@
});
{% endif %}
{% if mindstate_list %}
var ctx = document.getElementById("chart_mindstate").getContext("2d");
var gradient_stroke_1 = ctx.createLinearGradient(0, 230, 0, 50);
{% if wellbeing_list %}
var ctx = document.getElementById("chart_wellbeing").getContext("2d");
gradient_stroke_1.addColorStop(1, 'rgba(75, 192, 192, 0.4)');
gradient_stroke_1.addColorStop(0.75, 'rgba(75, 192, 192, 0.3)');
gradient_stroke_1.addColorStop(0.5, 'rgba(75, 192, 192, 0.2)');
gradient_stroke_1.addColorStop(0.25, 'rgba(75, 192, 192, 0)');
var border_color_pink = 'rgb(255, 99, 132)';
var gradient_stroke_pink = ctx.createLinearGradient(0, 230, 0, 50);
gradient_stroke_pink.addColorStop(1, 'rgba(255, 99, 132, 0.4)');
gradient_stroke_pink.addColorStop(0.75, 'rgba(255, 99, 132, 0.3)');
gradient_stroke_pink.addColorStop(0.5, 'rgba(255, 99, 132, 0.2)');
gradient_stroke_pink.addColorStop(0.25, 'rgba(255, 99, 132, 0)');
var border_color_orange = 'rgb(255, 159, 64)';
var gradient_stroke_orange = ctx.createLinearGradient(0, 230, 0, 50);
gradient_stroke_orange.addColorStop(1, 'rgba(255, 159, 64, 0.4)');
gradient_stroke_orange.addColorStop(0.75, 'rgba(255, 159, 64, 0.3)');
gradient_stroke_orange.addColorStop(0.5, 'rgba(255, 159, 64, 0.2)');
gradient_stroke_orange.addColorStop(0.25, 'rgba(255, 159, 64, 0)');
var border_color_green = 'rgb(75, 192, 192)';
var gradient_stroke_green = ctx.createLinearGradient(0, 230, 0, 50);
gradient_stroke_green.addColorStop(1, 'rgba(75, 192, 192, 0.4)');
gradient_stroke_green.addColorStop(0.75, 'rgba(75, 192, 192, 0.3)');
gradient_stroke_green.addColorStop(0.5, 'rgba(75, 192, 192, 0.2)');
gradient_stroke_green.addColorStop(0.25, 'rgba(75, 192, 192, 0)');
var border_color_blue = 'rgb(54, 162, 235)';
var gradient_stroke_blue = ctx.createLinearGradient(0, 230, 0, 50);
gradient_stroke_blue.addColorStop(1, 'rgba(54, 162, 235, 0.4)');
gradient_stroke_blue.addColorStop(0.75, 'rgba(54, 162, 235, 0.3)');
gradient_stroke_blue.addColorStop(0.5, 'rgba(54, 162, 235, 0.2)');
gradient_stroke_blue.addColorStop(0.25, 'rgba(54, 162, 235, 0)');
var border_color_yellow = 'rgb(255, 205, 86)';
var gradient_stroke_yellow = ctx.createLinearGradient(0, 230, 0, 50);
gradient_stroke_yellow.addColorStop(1, 'rgba(255, 205, 86, 0.4)');
gradient_stroke_yellow.addColorStop(0.75, 'rgba(255, 205, 86, 0.3)');
gradient_stroke_yellow.addColorStop(0.5, 'rgba(255, 205, 86, 0.2)');
gradient_stroke_yellow.addColorStop(0.25, 'rgba(255, 205, 86, 0)');
var mindstate_values = [
{% for state in mindstate_list %}
{
x: '{{ state.date | date:"d-m-Y" }}',
y: '{{ state.score }}'
},
{% for wellbeing in wellbeing_list %}
{
x: '{{ wellbeing.date | date:"d-m-Y" }}',
y: '{{ wellbeing.mind_state }}'
},
{% endfor %}
]
];
var mindstate_data = {
var sleep_values = [
{% for wellbeing in wellbeing_list %}
{
x: '{{ wellbeing.date | date:"d-m-Y" }}',
y: '{{ wellbeing.sleep }}'
},
{% endfor %}
];
var stress_values = [
{% for wellbeing in wellbeing_list %}
{
x: '{{ wellbeing.date | date:"d-m-Y" }}',
y: '{{ wellbeing.stress }}'
},
{% endfor %}
];
var fatigue_values = [
{% for wellbeing in wellbeing_list %}
{
x: '{{ wellbeing.date | date:"d-m-Y" }}',
y: '{{ wellbeing.fatigue }}'
},
{% endfor %}
];
var muscle_soreness_values = [
{% for wellbeing in wellbeing_list %}
{
x: '{{ wellbeing.date | date:"d-m-Y" }}',
y: '{{ wellbeing.muscle_soreness }}'
},
{% endfor %}
];
var wellbeing_data = {
datasets: [
{
label: 'Mindstate',
cubicInterpolationMode: 'monotone',
backgroundColor: gradient_stroke_1,
borderColor: 'rgb(75, 192, 192)',
pointBackgroundColor: 'rgb(75, 192, 192)',
backgroundColor: gradient_stroke_pink,
borderColor: border_color_pink,
pointBackgroundColor: border_color_pink,
fill: true,
data: mindstate_values,
},
{
label: 'Sleep',
cubicInterpolationMode: 'monotone',
backgroundColor: gradient_stroke_orange,
borderColor: border_color_orange,
pointBackgroundColor: border_color_orange,
fill: true,
data: sleep_values,
},
{
label: 'Stress',
cubicInterpolationMode: 'monotone',
backgroundColor: gradient_stroke_green,
borderColor: border_color_green,
pointBackgroundColor: border_color_green,
fill: true,
data: stress_values,
},
{
label: 'Fatigue',
cubicInterpolationMode: 'monotone',
backgroundColor: gradient_stroke_blue,
borderColor: border_color_blue,
pointBackgroundColor: border_color_blue,
fill: true,
data: fatigue_values,
},
{
label: 'Muscle',
cubicInterpolationMode: 'monotone',
backgroundColor: gradient_stroke_yellow,
borderColor: border_color_yellow,
pointBackgroundColor: border_color_yellow,
fill: true,
data: muscle_soreness_values,
},
],
};
new Chart(ctx, {
type: 'line',
data: mindstate_data,
data: wellbeing_data,
options: {
scales: {
x: {
@ -261,7 +368,8 @@
},
plugins: {
legend: {
display: false,
display: true,
position: 'bottom',
}
}
},

View File

@ -11,7 +11,7 @@
<h4 class=""><i class="icon-primary fal fa-laugh-wink"></i> Hi {{ user.username }} !</h4>
</div>
<div class="card-body">
Welcome to Ultron v0.72 <span class="text-muted">(last update : 19-11-2022)</span><br />
Welcome to Ultron v0.10 <span class="text-muted">(last update : 20-8-2023)</span><br />
This application is here to help coaches to manage the gymnasts (evolution, evaluation, routines, scores, …).
This tool is not perfect so feel free to make improvement proposals, bug reports, … by sending me an <a href="mailto:gregory@flyingacrobaticstrampoline.be">email</a>.<br />
<br />

View File

@ -91,20 +91,20 @@ def home(request):
# mettre tout ca en cache.
last_updated_gymnast = Gymnast.objects.filter(
Q(mindstate__created_at__gt=request.user.last_login)
Q(wellbeings__created_at__gt=request.user.last_login)
| Q(points__created_at__gt=request.user.last_login)
| Q(chronos__created_at__gt=request.user.last_login)
| Q(accident__created_at__gt=request.user.last_login)
| Q(injuries__created_at__gt=request.user.last_login)
| Q(known_skills__created_at__gt=request.user.last_login)
).distinct()
limit_date = timezone.now() - timedelta(days=14)
waiting_update_gymnast = Gymnast.objects.exclude(
Q(is_active=False)
| Q(mindstate__created_at__gte=limit_date)
| Q(wellbeings__created_at__gte=limit_date)
| Q(points__created_at__gte=limit_date)
| Q(chronos__created_at__gte=limit_date)
| Q(accident__created_at__gte=limit_date)
| Q(injuries__created_at__gte=limit_date)
| Q(known_skills__created_at__gte=limit_date)
).distinct()

View File

@ -11,11 +11,16 @@ from .models import (
Note,
Point,
Chrono,
Accident,
MindState,
Injury,
SLBridge,
WellBeing,
Stability,
InjuryType,
HeightWeight,
LearnedSkill,
ChronoDetails,
InjuryLocation,
SidePlankLegRaise,
GymnastHasRoutine,
SeasonInformation,
NumberOfRoutineDone,
@ -88,24 +93,80 @@ class PointAdmin(admin.ModelAdmin):
autocomplete_fields = ("gymnast", "event")
class AccidentAdmin(admin.ModelAdmin):
model = Accident
class InjuryLocationAdmin(admin.ModelAdmin):
model = InjuryLocation
fields = ("date", "gymnast", "skill", "informations") # educative
list_display = ("label",)
fields = ("label",)
search_fields = ("label",)
class InjuryTypeAdmin(admin.ModelAdmin):
model = InjuryType
list_display = ("label",)
fields = ("label",)
search_fields = ("label",)
class InjuryAdmin(admin.ModelAdmin):
model = Injury
fields = (
"date",
"gymnast",
"skill",
"injury_type",
"mechanism",
"location",
"body_side",
"diagnosis",
"nb_week_off",
"informations",
)
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_display = ("date", "gymnast", "skill") # educative
list_filter = ("date",)
list_display = (
"date",
"gymnast",
"mechanism",
"location",
"body_side",
"nb_week_off",
)
list_filter = (
("gymnast", RelatedDropdownFilter),
("mechanism", DropdownFilter),
("location", RelatedDropdownFilter),
("body_side", DropdownFilter),
)
date_hierarchy = "date"
search_fields = ("date", "gymnast") # educative
autocomplete_fields = ("gymnast", "skill")
class MindStateAdmin(admin.ModelAdmin):
model = MindState
class WellBeingAdmin(admin.ModelAdmin):
model = WellBeing
fields = ("gymnast", "date", "score", "informations")
fields = (
"gymnast",
"date",
"mind_state",
"sleep",
"stress",
"fatigue",
"muscle_soreness",
"informations",
)
readonly_fields = ("season", "week_number", "created_at", "updated_at")
list_display = ("date", "gymnast", "score")
list_display = (
"date",
"gymnast",
"mind_state",
"sleep",
"stress",
"fatigue",
"muscle_soreness",
)
list_filter = (
"date",
("gymnast", RelatedDropdownFilter),
@ -201,6 +262,8 @@ class SeasonInformationAdmin(admin.ModelAdmin):
"category",
"number_of_training_sessions_per_week",
"number_of_hours_per_week",
"number_of_s_and_c_sessions_per_week",
"number_of_s_and_c_hours_per_week",
# "club",
)
list_filter = (("gymnast", RelatedDropdownFilter),)
@ -211,15 +274,55 @@ class SeasonInformationAdmin(admin.ModelAdmin):
autocomplete_fields = ("gymnast",)
class SidePlankLegRaiseAdmin(admin.ModelAdmin):
model = SidePlankLegRaise
list_display = ("label",)
fields = ("label",)
search_fields = ("label",)
class SLBridgeAdmin(admin.ModelAdmin):
model = SLBridge
list_display = ("label",)
fields = ("label",)
search_fields = ("label",)
class StabilityAdmin(admin.ModelAdmin):
model = Stability
list_display = (
"gymnast",
"anterior_chain",
"posterior_chain_left",
"posterior_chain_right",
"leg_lowering",
)
list_filter = (("gymnast", RelatedDropdownFilter),)
search_fields = (
"gymnast__firstname",
"gymnast__lastname",
)
autocomplete_fields = ("gymnast",)
admin.site.register(Plan, PlanAdmin)
admin.site.register(Note, NoteAdmin)
admin.site.register(Point, PointAdmin)
admin.site.register(Chrono, ChronoAdmin)
admin.site.register(Accident, AccidentAdmin)
admin.site.register(MindState, MindStateAdmin)
admin.site.register(Injury, InjuryAdmin)
admin.site.register(WellBeing, WellBeingAdmin)
admin.site.register(InjuryType, InjuryTypeAdmin)
admin.site.register(LearnedSkill, LearnedSkillAdmin)
admin.site.register(HeightWeight, HeightWeightAdmin)
admin.site.register(ChronoDetails, ChronoDetailsAdmin)
admin.site.register(InjuryLocation, InjuryLocationAdmin)
admin.site.register(SeasonInformation, SeasonInformationAdmin)
admin.site.register(GymnastHasRoutine, GymnastHasRoutineAdmin)
admin.site.register(NumberOfRoutineDone, NumberOfRoutineDoneAdmin)
admin.site.register(SLBridge, SLBridgeAdmin)
admin.site.register(SidePlankLegRaise, SidePlankLegRaiseAdmin)
admin.site.register(Stability, StabilityAdmin)

View File

@ -7,8 +7,8 @@ from .models import (
Note,
Point,
Chrono,
Accident,
MindState,
Injury,
WellBeing,
HeightWeight,
LearnedSkill,
GymnastHasRoutine,
@ -180,10 +180,20 @@ class ScoreForm(forms.ModelForm):
)
class AccidentForm(forms.ModelForm):
class InjuryForm(forms.ModelForm):
class Meta:
model = Accident
fields = ("gymnast", "date", "nb_week_off", "informations")
model = Injury
fields = (
"gymnast",
"date",
"injury_type",
"mechanism",
"location",
"body_side",
"nb_week_off",
"diagnosis",
"informations",
)
widgets = {
"date": forms.DateInput(
attrs={
@ -194,13 +204,23 @@ class AccidentForm(forms.ModelForm):
),
"gymnast": forms.HiddenInput(),
"skill": forms.HiddenInput(),
"injury_type": forms.Select(attrs={"class": "form-control selectpicker"}),
"mechanism": forms.Select(attrs={"class": "form-control selectpicker"}),
"location": forms.Select(attrs={"class": "form-control selectpicker"}),
"body_side": forms.Select(attrs={"class": "form-control selectpicker"}),
"nb_week_off": forms.NumberInput(
attrs={"class": "form-control", "placeholder": "xx"}
),
"diagnosis": forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Informations about diagnosis", # pylint: disable=line-too-long
}
),
"informations": forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Informations about accident: context (why, where, …), consequencies, re-education exercices, …", # pylint: disable=line-too-long
"placeholder": "Informations about injury: consequencies, re-education exercices, …", # pylint: disable=line-too-long
}
),
}
@ -228,10 +248,19 @@ class AccidentForm(forms.ModelForm):
)
class MindStateForm(forms.ModelForm):
class WellBeingForm(forms.ModelForm):
class Meta:
model = MindState
fields = ("gymnast", "date", "score", "informations")
model = WellBeing
fields = (
"gymnast",
"date",
"mind_state",
"sleep",
"stress",
"fatigue",
"muscle_soreness",
"informations"
)
widgets = {
"gymnast": forms.HiddenInput(),
"date": forms.TextInput(
@ -242,7 +271,39 @@ class MindStateForm(forms.ModelForm):
}
),
"event": forms.HiddenInput(),
"score": forms.NumberInput(
"mind_state": forms.NumberInput(
attrs={
"class": "form-control",
"placeholder": "x",
"min": "0",
"max": "10",
}
),
"sleep": forms.NumberInput(
attrs={
"class": "form-control",
"placeholder": "x",
"min": "0",
"max": "10",
}
),
"stress": forms.NumberInput(
attrs={
"class": "form-control",
"placeholder": "x",
"min": "0",
"max": "10",
}
),
"fatigue": forms.NumberInput(
attrs={
"class": "form-control",
"placeholder": "x",
"min": "0",
"max": "10",
}
),
"muscle_soreness": forms.NumberInput(
attrs={
"class": "form-control",
"placeholder": "x",
@ -253,7 +314,7 @@ class MindStateForm(forms.ModelForm):
"informations": forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Informations about the psychological state of mind : context (why, where, …), possible consequencies, …", # pylint: disable=line-too-long
"placeholder": "Informations about the weel being state : context (why, where, when, …), possible consequencies, …", # pylint: disable=line-too-long
}
),
}

View File

@ -0,0 +1,111 @@
# Generated by Django 4.2 on 2023-07-10 08:58
from django.db import migrations, models
import django.db.models.deletion
import ultron.tools.models
class Migration(migrations.Migration):
dependencies = [
("planning", "0009_alter_event_date_begin_alter_event_date_end"),
("people", "0008_alter_gymnast_orientation"),
("followup", "0037_alter_chrono_chrono_type_and_more"),
]
operations = [
migrations.CreateModel(
name="WellBeing",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"date",
models.DateField(
default=ultron.tools.models.get_default_date,
verbose_name="Date",
),
),
("season", models.CharField(editable=False, max_length=9)),
("week_number", models.PositiveSmallIntegerField(editable=False)),
(
"informations",
models.TextField(
blank=True,
help_text="Only MarkDown is authorized",
null=True,
verbose_name="Comments",
),
),
(
"mind_state",
models.PositiveSmallIntegerField(verbose_name="Mind State"),
),
("sleep", models.PositiveSmallIntegerField(verbose_name="sleep")),
("stress", models.PositiveSmallIntegerField(verbose_name="stress")),
("fatigue", models.PositiveSmallIntegerField(verbose_name="fatigue")),
(
"muscle_soreness",
models.PositiveSmallIntegerField(verbose_name="Muscle Soreness"),
),
("created_at", models.DateTimeField(auto_now_add=True)),
("updated_at", models.DateTimeField(auto_now=True)),
(
"event",
models.ForeignKey(
blank=True,
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="wellbeings",
to="planning.event",
),
),
(
"gymnast",
models.ForeignKey(
default=None,
on_delete=django.db.models.deletion.CASCADE,
related_name="wellbeings",
to="people.gymnast",
),
),
],
options={
"abstract": False,
},
),
migrations.AddField(
model_name="seasoninformation",
name="number_of_s_and_c_hours_per_week",
field=models.PositiveSmallIntegerField(
blank=True, null=True, verbose_name="# S&C hours/w"
),
),
migrations.AddField(
model_name="seasoninformation",
name="number_of_s_and_c_sessions_per_week",
field=models.PositiveSmallIntegerField(
blank=True, null=True, verbose_name="# S&C training/w"
),
),
migrations.AlterField(
model_name="seasoninformation",
name="number_of_hours_per_week",
field=models.PositiveSmallIntegerField(verbose_name="# Hours/w"),
),
migrations.AlterField(
model_name="seasoninformation",
name="number_of_training_sessions_per_week",
field=models.PositiveSmallIntegerField(verbose_name="# Training/w"),
),
migrations.DeleteModel(
name="MindState",
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2 on 2023-07-11 08:49
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("people", "0008_alter_gymnast_orientation"),
("objective", "0015_alter_skill_position"),
("followup", "0038_wellbeing_and_more"),
]
operations = [
migrations.RenameModel(
old_name="Accident",
new_name="Injury",
),
migrations.AlterModelOptions(
name="injury",
options={"verbose_name": "Injury", "verbose_name_plural": "Injuries"},
),
]

View File

@ -0,0 +1,38 @@
# Generated by Django 4.2 on 2023-07-11 08:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("people", "0008_alter_gymnast_orientation"),
("objective", "0015_alter_skill_position"),
("followup", "0039_rename_accident_injury_alter_injury_options"),
]
operations = [
migrations.AlterField(
model_name="injury",
name="gymnast",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="injuries",
to="people.gymnast",
verbose_name="Gymnast",
),
),
migrations.AlterField(
model_name="injury",
name="skill",
field=models.ForeignKey(
blank=True,
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="injuries",
to="objective.skill",
verbose_name="Skill",
),
),
]

View File

@ -0,0 +1,74 @@
# Generated by Django 4.2 on 2023-07-11 08:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("followup", "0040_alter_injury_gymnast_alter_injury_skill"),
]
operations = [
migrations.CreateModel(
name="InjuryLocation",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("label", models.CharField(max_length=100)),
],
options={
"verbose_name": "Injury Location",
"verbose_name_plural": "Injury Locations",
},
),
migrations.AddField(
model_name="injury",
name="body_side",
field=models.PositiveSmallIntegerField(
choices=[(0, "Not Applicable"), (1, "Left"), (2, "Right"), (3, "Both")],
default=1,
verbose_name="Body side",
),
preserve_default=False,
),
migrations.AddField(
model_name="injury",
name="diagnosis",
field=models.TextField(
blank=True,
help_text="Only normal text is authorized",
null=True,
verbose_name="Diagnosis",
),
),
migrations.AddField(
model_name="injury",
name="mechanism",
field=models.PositiveSmallIntegerField(
choices=[(0, "Overuse"), (1, "Trauma")],
default=1,
verbose_name="Injury mechanism",
),
preserve_default=False,
),
migrations.AddField(
model_name="injury",
name="location",
field=models.ForeignKey(
default=1,
on_delete=django.db.models.deletion.CASCADE,
related_name="injuries",
to="followup.injurylocation",
verbose_name="Location",
),
preserve_default=False,
),
]

View File

@ -0,0 +1,81 @@
# Generated by Django 4.2 on 2023-07-13 13:32
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("followup", "0041_injurylocation_injury_body_side_injury_diagnosis_and_more"),
]
operations = [
migrations.CreateModel(
name="InjuryType",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("label", models.CharField(max_length=100)),
],
options={
"verbose_name": "Injury Type",
"verbose_name_plural": "Injury Types",
},
),
migrations.CreateModel(
name="SidePlankLegRaise",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("label", models.CharField(max_length=100)),
],
options={
"verbose_name": "Stability - SidePlankLegRaise",
},
),
migrations.CreateModel(
name="SLBridge",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("label", models.CharField(max_length=100)),
],
options={
"verbose_name": "Stability - SLBridge",
},
),
migrations.AddField(
model_name="injury",
name="injury_type",
field=models.ForeignKey(
blank=True,
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="injuries",
to="followup.injurytype",
verbose_name="Type",
),
),
]

View File

@ -0,0 +1,90 @@
# Generated by Django 4.2 on 2023-07-13 13:34
from django.db import migrations, models
import django.db.models.deletion
import ultron.tools.models
class Migration(migrations.Migration):
dependencies = [
("people", "0008_alter_gymnast_orientation"),
("followup", "0042_injurytype_sideplanklegraise_slbridge_and_more"),
]
operations = [
migrations.CreateModel(
name="Stability",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"date",
models.DateField(
default=ultron.tools.models.get_default_date,
verbose_name="Date",
),
),
("season", models.CharField(editable=False, max_length=9)),
("week_number", models.PositiveSmallIntegerField(editable=False)),
(
"anterior_chain",
models.PositiveSmallIntegerField(verbose_name="Anterior Chain"),
),
(
"posterior_chain_left",
models.PositiveSmallIntegerField(
verbose_name="Posterior Chain Left"
),
),
(
"posterior_chain_right",
models.PositiveSmallIntegerField(
verbose_name="Posterior Chain Right"
),
),
(
"leg_lowering",
models.PositiveSmallIntegerField(
choices=[
(0, "Not able to maintain pressure"),
(1, "Step 1: OK"),
(2, "Step 2: OK"),
(3, "Step 3: OK"),
],
verbose_name="Leg Lowering: lumbar stability",
),
),
(
"gymnast",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="stabilitytests",
to="people.gymnast",
),
),
(
"side_plank_leg_raise",
models.ManyToManyField(
related_name="stabilitytests", to="followup.sideplanklegraise"
),
),
(
"sl_bridge",
models.ManyToManyField(
related_name="stabilitytests", to="followup.slbridge"
),
),
],
options={
"verbose_name": "Stability",
"verbose_name_plural": "Stabilities",
},
),
]

View File

@ -0,0 +1,36 @@
# Generated by Django 4.2 on 2023-07-14 08:45
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("followup", "0043_stability"),
]
operations = [
migrations.AlterField(
model_name="injury",
name="injury_type",
field=models.ForeignKey(
blank=True,
default=None,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="injuries",
to="followup.injurytype",
verbose_name="Injury Type",
),
),
migrations.AlterField(
model_name="injury",
name="location",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="injuries",
to="followup.injurylocation",
verbose_name="Injury Location",
),
),
]

View File

@ -1,10 +1,7 @@
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
from datetime import date
import pendulum
from ultron.tools.models import Markdownizable, Seasonisable
from ultron.people.models import Gymnast
@ -12,6 +9,27 @@ from ultron.planning.models import Event
from ultron.objective.models import Educative, Skill, Routine
from ultron.location.models import Club
User = get_user_model()
INJURY_MECHANISM_CHOICE = (
(0, "Overuse"),
(1, "Trauma"),
)
INJURY_BODY_SIDE_CHOICE = (
(0, "Not Applicable"),
(1, "Left"),
(2, "Right"),
(3, "Both"),
)
LUMBAR_STABILITY_CHOICE = (
(0, "Not able to maintain pressure"),
(1, "Step 1: OK"),
(2, "Step 2: OK"),
(3, "Step 3: OK"),
)
ROUTINE_TYPE_CHOICE = (
(0, "Other"),
(1, "Q1R1"),
@ -126,32 +144,89 @@ class ChronoDetails(models.Model):
value = models.DecimalField(max_digits=5, decimal_places=3)
class Accident(Markdownizable, Seasonisable):
class InjuryLocation(models.Model):
"""
La classe `Accident` permet d'indiquer qu'un gymnaste a eu un accident, en liaison avec un
Classe représentant les localisations de blessures
"""
class Meta:
verbose_name = "Injury Location"
verbose_name_plural = "Injury Locations"
label = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return f"{self.label}"
class InjuryType(models.Model):
"""
Classe représentant les types de blessures
"""
class Meta:
verbose_name = "Injury Type"
verbose_name_plural = "Injury Types"
label = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return f"{self.label}"
class Injury(Markdownizable, Seasonisable):
"""
La classe `Injury` permet d'indiquer qu'un gymnaste a eu une blessure, en liaison avec un
skill ou non.
"""
class Meta:
verbose_name = "Accident"
verbose_name_plural = "Accidents"
verbose_name = "Injury"
verbose_name_plural = "Injuries"
# unique_together = ("gymnast", "skill", "date")
gymnast = models.ForeignKey(
Gymnast,
verbose_name="Gymnast",
related_name="accident",
related_name="injuries",
on_delete=models.CASCADE,
)
skill = models.ForeignKey(
"objective.Skill",
verbose_name="Skill",
related_name="accident",
related_name="injuries",
on_delete=models.SET_NULL,
default=None,
blank=True,
null=True,
)
location = models.ForeignKey(
InjuryLocation,
verbose_name="Injury Location",
related_name="injuries",
on_delete=models.CASCADE,
)
injury_type = models.ForeignKey(
InjuryType,
verbose_name="Injury Type",
related_name="injuries",
on_delete=models.SET_NULL,
default=None,
blank=True,
null=True,
)
body_side = models.PositiveSmallIntegerField(
choices=INJURY_BODY_SIDE_CHOICE, verbose_name="Body side"
)
mechanism = models.PositiveSmallIntegerField(
choices=INJURY_MECHANISM_CHOICE, verbose_name="Injury mechanism"
)
diagnosis = models.TextField(
null=True,
blank=True,
verbose_name="Diagnosis",
help_text="Only normal text is authorized",
)
nb_week_off = models.SmallIntegerField(
blank=True, null=True, verbose_name="# week off"
)
@ -159,13 +234,10 @@ class Accident(Markdownizable, Seasonisable):
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return "%s (%s)" % (
self.gymnast,
self.date,
)
return f"{self.gymnast} ({self.date}): {self.mechanism} on {self.location} {self.body_side}"
def timeline_representation(self):
return f"<li>{self.date:%d %b %Y} - Accident ({self.skill}): {self.nb_week_off} (weeks off)</li>"
return f"<li>{self.date:%d %b %Y} - Inuried on ({self.skill}): {self.nb_week_off} (weeks off)</li>"
class LearnedSkill(Seasonisable):
@ -282,13 +354,13 @@ class Point(models.Model):
)
class MindState(Markdownizable, Seasonisable):
class WellBeing(Markdownizable, Seasonisable):
"""
Représente l'état d'esprit psychologique d'un gymnaste
"""
gymnast = models.ForeignKey(
Gymnast, on_delete=models.CASCADE, default=None, related_name="mindstate"
Gymnast, on_delete=models.CASCADE, default=None, related_name="wellbeings"
)
event = models.ForeignKey(
Event,
@ -296,14 +368,18 @@ class MindState(Markdownizable, Seasonisable):
default=None,
blank=True,
null=True,
related_name="mindstate",
related_name="wellbeings",
)
score = models.PositiveSmallIntegerField(verbose_name="Score")
mind_state = models.PositiveSmallIntegerField(verbose_name="Mind State")
sleep = models.PositiveSmallIntegerField(verbose_name="sleep")
stress = models.PositiveSmallIntegerField(verbose_name="stress")
fatigue = models.PositiveSmallIntegerField(verbose_name="fatigue")
muscle_soreness = models.PositiveSmallIntegerField(verbose_name="Muscle Soreness")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return "%s - %s : %s" % (self.gymnast, self.date, self.score)
return "%s - %s : %s" % (self.gymnast, self.date, self.mind_state)
class GymnastHasRoutine(models.Model):
@ -460,10 +536,20 @@ class SeasonInformation(models.Model):
)
season = models.CharField(max_length=9)
number_of_training_sessions_per_week = models.PositiveSmallIntegerField(
verbose_name="# Training by week"
verbose_name="# Training/w"
)
number_of_hours_per_week = models.PositiveSmallIntegerField(
verbose_name="# Hours by week"
verbose_name="# Hours/w"
)
number_of_s_and_c_sessions_per_week = models.PositiveSmallIntegerField(
verbose_name="# S&C training/w",
blank=True,
null=True,
)
number_of_s_and_c_hours_per_week = models.PositiveSmallIntegerField(
verbose_name="# S&C hours/w",
blank=True,
null=True,
)
category = models.PositiveSmallIntegerField(
choices=CATEGORY_CHOICES_ARRAY,
@ -483,3 +569,58 @@ class SeasonInformation(models.Model):
self.category,
self.club,
)
class SLBridge(models.Model):
""" """
class Meta:
verbose_name = "Stability - SLBridge"
label = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return f"{self.label}"
class SidePlankLegRaise(models.Model):
""" """
class Meta:
verbose_name = "Stability - SidePlankLegRaise"
label = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return f"{self.label}"
class Stability(Seasonisable):
"""Classe représentant l'intensité d'un entraînement"""
class Meta:
verbose_name = "Stability"
verbose_name_plural = "Stabilities"
gymnast = models.ForeignKey(
Gymnast, on_delete=models.CASCADE, related_name="stabilitytests"
)
anterior_chain = models.PositiveSmallIntegerField(
verbose_name="Anterior Chain"
)
posterior_chain_left = models.PositiveSmallIntegerField(
verbose_name="Posterior Chain Left"
)
posterior_chain_right = models.PositiveSmallIntegerField(
verbose_name="Posterior Chain Right"
)
leg_lowering = models.PositiveSmallIntegerField(
choices=LUMBAR_STABILITY_CHOICE,
verbose_name="Leg Lowering: lumbar stability",
)
sl_bridge = models.ManyToManyField(
SLBridge, related_name="stabilitytests", symmetrical=False
)
side_plank_leg_raise = models.ManyToManyField(
SidePlankLegRaise, related_name="stabilitytests", symmetrical=False
)

View File

@ -52,43 +52,43 @@ class URLTestCase(TestCase):
self.assertEqual(resolve("/follow-up/score/add/").view_name, "score_create")
self.assertEqual(resolve("/follow-up/score/edit/1/").view_name, "score_update")
# Accident URL
# Injury URL
self.assertEqual(
resolve("/follow-up/accident/search/").view_name, "accident_search"
resolve("/follow-up/injury/search/").view_name, "injury_search"
)
self.assertEqual(resolve("/follow-up/accident/").view_name, "accident_list")
self.assertEqual(resolve("/follow-up/injury/").view_name, "injury_list")
self.assertEqual(
resolve("/follow-up/accident/add/").view_name, "accident_create"
resolve("/follow-up/injury/add/").view_name, "injury_create"
)
self.assertEqual(
resolve("/follow-up/accident/add/1/").view_name,
"accident_create_for_gymnast",
resolve("/follow-up/injury/add/1/").view_name,
"injury_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/accident/edit/1/").view_name, "accident_update"
resolve("/follow-up/injury/edit/1/").view_name, "injury_update"
)
self.assertEqual(
resolve("/follow-up/accident/1/").view_name, "accident_details"
resolve("/follow-up/injury/1/").view_name, "injury_details"
)
# Mindstate URL
self.assertEqual(resolve("/follow-up/mindstate/").view_name, "mindstate_list")
self.assertEqual(resolve("/follow-up/wellbeing/").view_name, "wellbeing_list")
self.assertEqual(
resolve("/follow-up/mindstate/gymnast/1/").view_name,
"mindstate_list_for_gymnast",
resolve("/follow-up/wellbeing/gymnast/1/").view_name,
"wellbeing_list_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/mindstate/add/").view_name, "mindstate_create"
resolve("/follow-up/wellbeing/add/").view_name, "wellbeing_create"
)
self.assertEqual(
resolve("/follow-up/mindstate/add/1/").view_name,
"mindstate_create_for_gymnast",
resolve("/follow-up/wellbeing/add/1/").view_name,
"wellbeing_create_for_gymnast",
)
self.assertEqual(
resolve("/follow-up/mindstate/edit/1/").view_name, "mindstate_update"
resolve("/follow-up/wellbeing/edit/1/").view_name, "wellbeing_update"
)
self.assertEqual(
resolve("/follow-up/mindstate/1/").view_name, "mindstate_details"
resolve("/follow-up/wellbeing/1/").view_name, "wellbeing_details"
)
# HeightWeigh URL

View File

@ -54,7 +54,7 @@ urlpatterns = [
path(r"learnedskill/new/", views.gymnast_learn_skill, name="gymnast_learn_skill"),
#
#
# Score
# SCORE
path(r"score/", views.score_listing, name="score_listing"),
path(
r"score/gymnast/<int:gymnast_id>/",
@ -72,51 +72,71 @@ urlpatterns = [
),
#
#
# Accident
path(r"accident/search/", views.accident_listing, name="accident_search"),
path(r"accident/", views.accident_listing, name="accident_list"),
path(r"accident/add/", views.accident_create_or_update, name="accident_create"),
# INJURY
path(r"injury/search/", views.injury_listing, name="injury_search"),
path(r"injury/", views.injury_listing, name="injury_list"),
path(r"injury/add/", views.injury_create_or_update, name="injury_create"),
path(
r"accident/add/<int:gymnast_id>/",
views.accident_create_or_update,
name="accident_create_for_gymnast",
r"injury/add/<int:gymnast_id>/",
views.injury_create_or_update,
name="injury_create_for_gymnast",
),
path(
r"accident/edit/<int:accident_id>/",
views.accident_create_or_update,
name="accident_update",
r"injury/edit/<int:injury_id>/",
views.injury_create_or_update,
name="injury_update",
),
path(
r"accident/<int:accident_id>/", views.accident_detail, name="accident_details"
r"injury/<int:injury_id>/", views.injury_detail, name="injury_details"
),
#
#
# Mindstate
path(r"mindstate/", views.mindstate_listing, name="mindstate_list"),
# STABILITY
path(r"stability/", views.stability_listing, name="stability_list"),
path(r"stability/gymnast/<int:gymnast_id>/", views.stability_listing, name="stability_list"),
# path(r"stability/search/", views.injury_listing, name="stability_search"),
# path(r"stability/add/", views.injury_create_or_update, name="stability_create"),
# path(
# r"stability/add/<int:gymnast_id>/",
# views.injury_create_or_update,
# name="injury_create_for_gymnast",
# ),
# path(
# r"stability/edit/<int:injury_id>/",
# views.injury_create_or_update,
# name="injury_update",
# ),
path(
r"mindstate/gymnast/<int:gymnast_id>/",
views.mindstate_listing,
name="mindstate_list_for_gymnast",
),
path(r"mindstate/add/", views.mindstate_create_or_update, name="mindstate_create"),
path(
r"mindstate/add/<int:gymnast_id>/",
views.mindstate_create_or_update,
name="mindstate_create_for_gymnast",
),
path(
r"mindstate/edit/<int:mindstate_id>/",
views.mindstate_create_or_update,
name="mindstate_update",
),
path(
r"mindstate/<int:mindstate_id>/",
views.mindstate_detail,
name="mindstate_details",
r"stability/<int:stability_id>/", views.stability_detail, name="stability_details"
),
#
#
# Height/Weight
# WELLBEING
path(r"wellbeing/", views.wellbeing_listing, name="wellbeing_list"),
path(
r"wellbeing/gymnast/<int:gymnast_id>/",
views.wellbeing_listing,
name="wellbeing_list_for_gymnast",
),
path(r"wellbeing/add/", views.wellbeing_create_or_update, name="wellbeing_create"),
path(
r"wellbeing/add/<int:gymnast_id>/",
views.wellbeing_create_or_update,
name="wellbeing_create_for_gymnast",
),
path(
r"wellbeing/edit/<int:wellbeing_id>/",
views.wellbeing_create_or_update,
name="wellbeing_update",
),
path(
r"wellbeing/<int:wellbeing_id>/",
views.wellbeing_detail,
name="wellbeing_details",
),
#
#
# HEIGH/WEIGHT
path(
r"heightweight/gymnast/<int:gymnast_id>/",
views.heightweight_listing,
@ -139,7 +159,7 @@ urlpatterns = [
),
#
#
# Routine Done
# ROUTINEDONE
path(
r"routinedone/add/",
views.routinedone_create_or_update,

View File

@ -2,13 +2,11 @@ from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
from django.http import HttpResponse, HttpResponseRedirect
from django.db.models import Q, Min, Avg, Max, Sum
from django.db.models import Q
from django.urls import reverse
from django.contrib.auth import get_user_model
User = get_user_model()
from ultron.people.models import Gymnast
from ultron.planning.models import Event
from ultron.objective.models import Skill
@ -18,11 +16,11 @@ from .models import (
Note,
Point,
Chrono,
Accident,
MindState,
Injury,
WellBeing,
Stability,
LearnedSkill,
HeightWeight,
ChronoDetails,
SeasonInformation,
NumberOfRoutineDone,
)
@ -32,24 +30,15 @@ from .forms import (
NoteForm,
ScoreForm,
ChronoForm,
AccidentForm,
MindStateForm,
InjuryForm,
WellBeingForm,
HeightWeightForm,
LearnedSkillForm,
SeasonInformationForm,
NumberOfRoutineDoneForm,
)
from ultron.tools.date_week_transition import (
from_date_to_week_number,
from_week_number_to_date,
)
from ultron.tools.models import Season
from datetime import date, datetime
import pendulum
import re
User = get_user_model()
@login_required
@ -351,42 +340,41 @@ def score_listing(request, gymnast_id=None):
@login_required
@require_http_methods(["GET"])
def accident_listing(request):
def injury_listing(request):
"""
Récupère la liste des accidents.
Récupère la liste des blessures.
Si c'est un gymnaste qui est connecté, il ne peut récupérer que la liste de ses accidents.
Si c'est un autre utilisateur (entraîneur), la liste peut répondre à un pattern si celui-ci est
définit.
Si c'est un entraîneur, la liste peut répondre à un pattern si celui-ci est définit.
"""
if request.user.groups.filter(name="trainer").exists():
pattern = request.GET.get("pattern", None)
if pattern:
accident_list = Accident.objects.filter(
injuries_list = Injury.objects.filter(
Q(gymnast__last_name__icontains=pattern)
| Q(gymnast__first_name__icontains=pattern)
)
else:
accident_list = Accident.objects.all()
injuries_list = Injury.objects.all()
else:
accident_list = Accident.objects.filter(
injuries_list = Injury.objects.filter(
Q(gymnast__last_name=request.user.last_name)
& Q(gymnast__first_name=request.user.first_name)
)
context = {"accident_list": accident_list}
return render(request, "followup/accidents/list.html", context)
context = {"injuries_list": injuries_list}
return render(request, "followup/injuries/list.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def accident_create_or_update(request, accident_id=None, gymnast_id=None):
def injury_create_or_update(request, injury_id=None, gymnast_id=None):
"""
Formulaire de création d'un nouvel accident.
"""
if accident_id:
accident = get_object_or_404(Accident, pk=accident_id)
if injury_id:
accident = get_object_or_404(Injury, pk=injury_id)
data = {
"gymnast_related": accident.gymnast,
"skill_related": accident.skill,
@ -399,62 +387,62 @@ def accident_create_or_update(request, accident_id=None, gymnast_id=None):
data = {"gymnast": gymnast_id, "gymnast_related": str(gymnast)}
if request.method == "POST":
form = AccidentForm(request.POST, instance=accident)
form = InjuryForm(request.POST, instance=accident)
if form.is_valid():
accident = form.save()
return HttpResponseRedirect(
reverse("accident_details", args=(accident.pk,))
reverse("injury_details", args=(accident.pk,))
)
else:
return render(request, "followup/accidents/create.html", {"form": form})
return render(request, "followup/injuries/create.html", {"form": form})
form = AccidentForm(instance=accident, initial=data)
context = {"form": form, "accident_id": accident_id}
return render(request, "followup/accidents/create.html", context)
form = InjuryForm(instance=accident, initial=data)
context = {"form": form, "injury_id": injury_id}
return render(request, "followup/injuries/create.html", context)
@login_required
@require_http_methods(["GET"])
def accident_detail(request, accident_id):
def injury_detail(request, injury_id):
"""
Récupère toutes les informations d'un accident.
"""
accident = get_object_or_404(Accident, pk=accident_id)
return render(request, "followup/accidents/details.html", {"accident": accident})
accident = get_object_or_404(Injury, pk=injury_id)
return render(request, "followup/injuries/details.html", {"accident": accident})
@login_required
@require_http_methods(["GET"])
def mindstate_listing(request, gymnast_id=None):
def wellbeing_listing(request, gymnast_id=None):
"""
Récupère la liste des évaluations mentales suivant (d'un gymnaste si définit en paramètre).
"""
gymnast = None
if gymnast_id:
mindstate_list = MindState.objects.filter(gymnast=gymnast_id)
wellbeing_list = WellBeing.objects.filter(gymnast=gymnast_id)
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
else:
mindstate_list = MindState.objects.all()
wellbeing_list = WellBeing.objects.all()
context = {"mindstate_list": mindstate_list, "gymnast": gymnast}
return render(request, "followup/mindstates/list.html", context)
context = {"wellbeing_list": wellbeing_list, "gymnast": gymnast}
return render(request, "followup/wellbeings/list.html", context)
@login_required
@require_http_methods(["GET", "POST"])
def mindstate_create_or_update(
request, mindstate_id=None, gymnast_id=None, event_id=None
def wellbeing_create_or_update(
request, wellbeing_id=None, gymnast_id=None, event_id=None
):
"""
Formulaire de création d'un nouvel accident.
"""
if mindstate_id:
mindstate = get_object_or_404(MindState, pk=mindstate_id)
data = {"gymnast_related": mindstate.gymnast, "event_related": mindstate.event}
if wellbeing_id:
wellbeing = get_object_or_404(WellBeing, pk=wellbeing_id)
data = {"gymnast_related": wellbeing.gymnast, "event_related": wellbeing.event}
else:
mindstate = None
wellbeing = None
data = None
if gymnast_id is not None:
gymnast = get_object_or_404(Gymnast, pk=gymnast_id)
@ -464,29 +452,29 @@ def mindstate_create_or_update(
data = {"event": event_id, "event_related": str(event)}
if request.method == "POST":
form = MindStateForm(request.POST, instance=mindstate)
form = WellBeingForm(request.POST, instance=wellbeing)
if form.is_valid():
mindstate = form.save()
wellbeing = form.save()
return HttpResponseRedirect(
reverse("mindstate_details", args=(mindstate.pk,))
reverse("wellbeing_details", args=(wellbeing.pk,))
)
else:
return render(request, "followup/mindstates/create.html", {"form": form})
return render(request, "followup/wellbeings/create.html", {"form": form})
form = MindStateForm(instance=mindstate, initial=data)
context = {"form": form, "mindstate_id": mindstate_id}
return render(request, "followup/mindstates/create.html", context)
form = WellBeingForm(instance=wellbeing, initial=data)
context = {"form": form, "wellbeing_id": wellbeing_id}
return render(request, "followup/wellbeings/create.html", context)
@login_required
@require_http_methods(["GET"])
def mindstate_detail(request, mindstate_id):
def wellbeing_detail(request, wellbeing_id):
"""
Récupère toutes les informations d'une évaluation psychologique.
"""
mindstate = get_object_or_404(MindState, pk=mindstate_id)
return render(request, "followup/mindstates/details.html", {"mindstate": mindstate})
wellbeing = get_object_or_404(WellBeing, pk=wellbeing_id)
return render(request, "followup/wellbeings/details.html", {"wellbeing": wellbeing})
@login_required
@ -752,6 +740,41 @@ def season_information_listing(request, gymnast_id=None):
season_information_list = SeasonInformation.objects.filter(gymnast=gymnast_id)
else:
season_information_list = SeasonInformation.objects.all()
gymnast = None
context = {"season_information_list": season_information_list, "gymnast": gymnast}
return render(request, "followup/seasoninformations/list.html", context)
@login_required
@require_http_methods(["GET"])
def stability_listing(request, gymnast_id=None):
"""Liste toutes les records de la table stability"""
if gymnast_id is not None:
gymnast = Gymnast.objects.get(pk=gymnast_id)
stabilities_list = Stability.objects.filter(gymnast=gymnast_id)
else:
stabilities_list = Stability.objects.all()
gymnast = None
context = {"stabilities_list": stabilities_list, "gymnast": gymnast}
return render(request, "followup/stabilities/list.html", context)
@login_required
@require_http_methods(["GET"])
def stability_detail(request, stability_id):
"""
Récupère toutes les informations d'une stability.
"""
stability = get_object_or_404(Stability, pk=stability_id)
stability_sl_bridge = stability.sl_bridge.all()
stability_side_plank_leg_raise = stability.side_plank_leg_raise.all()
context = {
"stability": stability,
"stability_sl_bridge": stability_sl_bridge,
"stability_side_plank_leg_raise": stability_side_plank_leg_raise
}
return render(request, "followup/stabilities/details.html", context)

View File

@ -32,7 +32,7 @@ gymnast_urlpatterns = [
name="gymnast_display_events_and_notes",
),
path(
r"details/<int:gymnast_id>/accident/",
r"details/<int:gymnast_id>/injury/",
views.gymnast_display_accident,
name="gymnast_display_accident",
),
@ -42,9 +42,9 @@ gymnast_urlpatterns = [
name="gymnast_display_scores_chrono",
),
path(
r"details/<int:gymnast_id>/mindstate/",
views.gymnast_display_mindstate,
name="gymnast_display_mindstate",
r"details/<int:gymnast_id>/wellbeing/",
views.gymnast_display_wellbeing,
name="gymnast_display_wellbeing",
),
path(
r"details/<int:gymnast_id>/physiological/",

View File

@ -37,8 +37,8 @@ from ultron.followup.models import (
Skill,
Point,
Chrono,
Accident,
MindState,
Injury,
WellBeing,
LearnedSkill,
HeightWeight,
SeasonInformation,
@ -240,8 +240,8 @@ def gymnast_display_accident(request, gymnast_id):
"""
Renvoie la liste des accidents d'un gymnaste.
"""
accident_list = Accident.objects.filter(gymnast=gymnast_id)
context = {"accident_list": accident_list, "gymnast_id": gymnast_id}
injuries_list = Injury.objects.filter(gymnast=gymnast_id)
context = {"injuries_list": injuries_list, "gymnast_id": gymnast_id}
return render(request, "people/gymnasts/list_accident.html", context)
@ -251,15 +251,15 @@ def gymnast_display_physiological(request, gymnast_id):
"""
Renvoie les listes des tailles/poids, état d'esprit et accidents.
"""
accident_list = Accident.objects.filter(gymnast=gymnast_id).order_by("date")
mindstate_list = MindState.objects.filter(gymnast=gymnast_id).order_by("date")
injuries_list = Injury.objects.filter(gymnast=gymnast_id).order_by("date")
wellbeing_list = WellBeing.objects.filter(gymnast=gymnast_id).order_by("date")
height_weight_list = HeightWeight.objects.filter(gymnast=gymnast_id).order_by(
"date"
)
context = {
"accident_list": accident_list,
"mindstate_list": mindstate_list,
"injuries_list": injuries_list,
"wellbeing_list": wellbeing_list,
"height_weight_list": height_weight_list,
"gymnast_id": gymnast_id,
}
@ -296,17 +296,17 @@ def gymnast_display_scores_chrono(request, gymnast_id):
@login_required
@require_http_methods(["GET"])
def gymnast_display_mindstate(request, gymnast_id):
def gymnast_display_wellbeing(request, gymnast_id):
"""
Selectionne tous les scores réalisés par le gymnaste
"""
mindstate_list = MindState.objects.filter(gymnast=gymnast_id).order_by("-date")
wellbeing_list = WellBeing.objects.filter(gymnast=gymnast_id).order_by("-date")
context = {
"mindstate_list": mindstate_list,
"wellbeing_list": wellbeing_list,
"gymnast_id": gymnast_id,
}
return render(request, "people/gymnasts/list_mindstate.html", context)
return render(request, "people/gymnasts/list_wellbeing.html", context)
@login_required
@ -583,7 +583,7 @@ def __get_distinct_followup_season_for_gymnast(gymnast_id):
.order_by("season")
)
season_list += list(
gymnast.mindstate.values_list("season", flat=True)
gymnast.wellbeing.values_list("season", flat=True)
.distinct("season")
.order_by("season")
)
@ -633,7 +633,7 @@ def __get_distinct_week_number_for_season_and_gymnast(gymnast_id, season):
.order_by("week_number")
)
weeknumber_list += list(
gymnast.mindstate.values_list("week_number", flat=True)
gymnast.wellbeing.values_list("week_number", flat=True)
.filter(season=season)
.distinct("week_number")
.order_by("week_number")
@ -709,15 +709,15 @@ def generate_report(request, gymnast_id, season=None, week_number=None):
#
# PHYSIOLOGICAL INFORMATIONS
#
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by("-date")
last_mindstate = mindstate_queryset.first()
lasts_mindstate = list(mindstate_queryset.values_list("score", flat=True)[1:6])
wellbeing_queryset = WellBeing.objects.filter(gymnast=gymnast).order_by("-date")
last_wellbeing = wellbeing_queryset.first()
lasts_wellbeing = list(wellbeing_queryset.values_list("score", flat=True)[1:6])
have_physiological = False
if lasts_mindstate:
mindstate_analyse = analyse_score(last_mindstate.score, lasts_mindstate)
if lasts_wellbeing:
wellbeing_analyse = analyse_score(last_wellbeing.score, lasts_wellbeing)
else:
mindstate_analyse = None
wellbeing_analyse = None
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by(
"-date"
@ -928,8 +928,8 @@ def generate_report(request, gymnast_id, season=None, week_number=None):
"gymnast": gymnast,
"today": date_begin,
"season": season,
"last_mindstate": last_mindstate,
"mindstate_analyse": mindstate_analyse,
"last_wellbeing": last_wellbeing,
"wellbeing_analyse": wellbeing_analyse,
"last_height_weigth": last_height_weigth,
"height_analyse": height_analyse,
"weight_analyse": weight_analyse,

View File

@ -1,15 +1,11 @@
import locale
import os
import re
from datetime import date, datetime, timedelta
from datetime import date, timedelta
from statistics import mean
import pendulum
import yaml
from django.conf import settings
from django.db.models import F, Max, Q
from django.db.models import F, Q
from PIL import Image
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
@ -20,8 +16,7 @@ from ultron.followup.models import (
Plan,
Point,
Chrono,
Accident,
MindState,
WellBeing,
HeightWeight,
LearnedSkill,
)
@ -33,7 +28,6 @@ from ultron.planning.models import Event
from .date_week_transition import from_date_to_week_number
import environ
from pathlib import Path
# Initialise environment variables
env = environ.Env()
@ -271,14 +265,14 @@ class GymnastReportDocument(PDFDocument):
)
data = []
mindstate_queryset = MindState.objects.filter(gymnast=gymnast).order_by("-date")
last_mindstate = mindstate_queryset.first()
lasts_mindstate = list(mindstate_queryset.values_list("score", flat=True)[1:6])
wellbeing_queryset = WellBeing.objects.filter(gymnast=gymnast).order_by("-date")
last_wellbeing = wellbeing_queryset.first()
lasts_wellbeing = list(wellbeing_queryset.values_list("score", flat=True)[1:6])
have_physiological = False
if lasts_mindstate:
res = self.analyse_score(last_mindstate.score, lasts_mindstate)
data.append(["Mind state", str(last_mindstate.score), res])
if lasts_wellbeing:
res = self.analyse_score(last_wellbeing.score, lasts_wellbeing)
data.append(["Mind state", str(last_wellbeing.score), res])
have_physiological = True
height_weight_queryset = HeightWeight.objects.filter(gymnast=gymnast).order_by(