diff --git a/CHANGELOG.md b/CHANGELOG.md index b1bafa6b53353f9ab7a1c466a6dbf3433d632fdd..b5957684bd4eaa783272ba2c409bad150c828423 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,17 @@ # Change Log -## Version ??? - Coming soon +## Version 2.0.0-beta - Coming soon - Added a form that allows admins to send emails to all users - Added a form for users to submit activities - Added a changeable caption for the planning +- Added fixes/improvement from 48h des jeux: + - bug fixed in activity submission form + - new validator that checks the number of slots for each activity in the planning + - fixed room display on activity page + - fixed planning info displayed on activity even when planning hidden + - added boolean field to show host email on activity + - added boolean field to separate showing slot on planning and next to activity ## Version 1.2.8 - 2021-05-06 diff --git a/Makefile b/Makefile index af20cb8cfe3230d5f656318dcdf7b302340b3558..ce6d13e188473d2ba83b3c8091566e189bb7140f 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,8 @@ SECRET := interludes/secret.py .PHONY: help help: ## Show this help - @egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' + @echo "make: list of useful targets :" + @egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' .PHONY: install install: ## Install requirements diff --git a/README.md b/README.md index e1621c5cf360f3773b9961eff701e578a5805eb4..17fccba1dffbc0854ad4263db1261df97f003f34 100644 --- a/README.md +++ b/README.md @@ -137,4 +137,7 @@ A.K.A. la liste des trucs utiles que j'ai pas eu le temps d'ajouter - [Le site des interludes 2021](https://interludes.ens.fr) - [Le github de l'algorithme de répartition](https://github.com/Imakoala/InterludesMatchings) -- [Le wiki de Paris-Saclay](https://wiki.crans.org/VieBdl/InterLudes) qui recensent les visuels, sites webs et photos des interludes passées. +- [Le wiki de Paris-Saclay](https://wiki.crans.org/VieBdl/InterLudes) qui recense les visuels, sites webs et photos des interludes passées. +- [Le gitlab du site des 48h des jeux](https://git.eleves.ens.fr/dlesbre/48h-des-jeux) un événement très similaire intra-ENS Ulm, c'est fork de ce répo. +- [Le site des 48h des jeux](https://48hdesjeux.cof.ens.fr/) +- [Le site du club jeu d'Ulm](https://jeux.cof.ens.fr/) diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py index dfcc7658da54d79a045b4692f03c4b87f56f9780..0422e1388a3fef5a62602ea0f455abafa1082d49 100644 --- a/accounts/migrations/0001_initial.py +++ b/accounts/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.7 on 2021-09-13 17:01 +# Generated by Django 3.2.7 on 2021-10-05 18:45 from django.db import migrations, models import django.utils.timezone diff --git a/accounts/templates/password_reset.html b/accounts/templates/password_reset.html index a1a6ebc919b9d838e82e385e9b1676a65fd99220..1367f843aa439dc79a62b6f277a8315fba7e3e32 100644 --- a/accounts/templates/password_reset.html +++ b/accounts/templates/password_reset.html @@ -1,15 +1,15 @@ {% extends 'base.html' %} {% block "content" %} - <h2>Mot de passe oublié ?</h2> - <p>Saissisez votre adresse email ci-dessous pour recevoir un lien de réinitialisation du mot de passe.</p> + <h2>Mot de passe oublié ?</h2> + <p>Saissisez votre adresse email ci-dessous pour recevoir un lien de réinitialisation du mot de passe.</p> - <form method="POST"> - {% csrf_token %} - {{ form.as_p }} + <form method="POST"> + {% csrf_token %} + {{ form.as_p }} <div class="flex"> - <input type="submit" value="Valider"> + <input type="submit" value="Valider"> <a class="button" href="{% url 'accounts:login' %}">Annuler</a> </div> - </form> + </form> {% endblock %} diff --git a/accounts/templates/password_reset_confirm.html b/accounts/templates/password_reset_confirm.html index 8be0bda97ccd507b97a938bc9226d36e45467eeb..eee4ac4744f4c9decf1a2cd06d321cdfa62efb84 100644 --- a/accounts/templates/password_reset_confirm.html +++ b/accounts/templates/password_reset_confirm.html @@ -6,12 +6,12 @@ <h2>Saissisez un nouveau mot de passe</h2> <form method="POST"> - {% csrf_token %} - {{ form.as_p }} - <div class="flex"> - <input type="submit" value="Changer mon mot de passe"> - <a class="button" href="{% url 'accounts:login' %}">Annuler</a> - </div> + {% csrf_token %} + {{ form.as_p }} + <div class="flex"> + <input type="submit" value="Changer mon mot de passe"> + <a class="button" href="{% url 'accounts:login' %}">Annuler</a> + </div> </form> {% else %} @@ -19,8 +19,8 @@ <h2>Lien invalide</h2> <p>Le lien de réinitialisation est invalide, peut-être a-t-il déjà été utilisé. - Veuillez <a href="{% url 'accounts:password_reset' %}">demander un nouveau lien</a>. + Veuillez <a href="{% url 'accounts:password_reset' %}">demander un nouveau lien</a>. </p> {% endif %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/admin_pages/templates/admin.html b/admin_pages/templates/admin.html index 8aa98171d83d0db85ed225b264cf825cb1e976b8..125b572bf47ad689571fd1119e21ca0aafcb4134 100644 --- a/admin_pages/templates/admin.html +++ b/admin_pages/templates/admin.html @@ -31,10 +31,12 @@ <li>Fermeture : {{ settings.inscriptions_end|default:"non fixée" }}</li> </ul> </li> + <li>Les emails des orgas sont {% if settings.show_host_emails %}affichés sur la page activité{% else %}masqués{% endif %}.</li> <li>Le planning {% if settings.display_planning %}est affiché{% else %}n'est pas affiché{% endif %}.</li> <li>La répartition des activités {% if settings.activities_allocated %}est effectuée et affichée{% else %}n'est pas faite/affichée{% endif %}.</li> <li>{% if settings.global_message %}Un message global est affiché{% else %}Aucun message global{% endif %}.</li> <li>Le lien du serveur discord {% if settings.discord_link %}est affiché{% else %}n'est pas affiché{% endif %}.</li> + <li>L'envoi d'email en masse est {% if settings.allow_mass_email %}activé{% else %}désactivé{% endif %}</li> </ul> <h2>Métriques</h2> @@ -69,7 +71,7 @@ <div class="nb_small">{{ metrics.sleeps }}</div> </div> </div> -<!-- + <div class="flex wrap lines"> <div class="stat"> <div class="qty">Repas</div> @@ -100,7 +102,7 @@ <div class="nb_small">{{ metrics.meal6 }}</div> </div> </div> ---> + <div class="flex wrap lines"> <div class="stat"> <div class="qty">Activités</div> @@ -167,6 +169,10 @@ <h2>Prévisualisation du planning</h2> + <ul class="messagelist"> + {{ planning_validation|safe }} + </ul> + <p>Vous pouver uploader une version PDF dans le réglages (depuis django-admin)</p> {% include "_planning.html" %} diff --git a/admin_pages/views.py b/admin_pages/views.py index 31283f30f26347fd253efdb3927442a16713094a..53907d93e06b6652bd9c7fee0818925b4fe9840b 100644 --- a/admin_pages/views.py +++ b/admin_pages/views.py @@ -169,6 +169,24 @@ class AdminView(SuperuserRequiredMixin, TemplateView): ) return '<li class="success">Aucun inscrit plusieurs fois à une même activité</li>' + def planning_validation(self): + """Vérifie que toutes les activités ont le bon nombre de créneaux + dans le planning""" + errors = "" + activities = models.ActivityModel.objects.all() + for activity in activities: + nb_wanted = activity.desired_slot_nb + nb_got = activity.slots.count() + if nb_wanted != nb_got: + errors += '<br> •  "{}" souhaite {} crénaux mais en a {}.'.format( + activity.title, nb_wanted, nb_got + ) + if errors: + return '<li class="error">Certaines activités ont trop/pas assez de crénaux :{}</li>'.format( + errors + ) + return '<li class="success">Toutes les activités ont le bon nombre de crénaux</li>' + def validate_activity_allocation(self): settings = SiteSettings.load() validations = '<ul class="messagelist">' @@ -207,7 +225,8 @@ class AdminView(SuperuserRequiredMixin, TemplateView): "validations": validations, "user_email_nb": user_email_nb, "orga_email_nb": orga_email_nb, - "validation_errors": '<li class="error">' in validations + "validation_errors": '<li class="error">' in validations, + "planning_validation": self.planning_validation(), } def get_context_data(self, *args, **kwargs): @@ -230,7 +249,7 @@ class ExportActivities(SuperuserRequiredMixin, CSVWriteView): # The key is "host_id" but listed as "host" in auto-found field names # which leads to an error... 'id', 'display', 'title', 'act_type', 'game_type', 'description', - 'desc_as_html', 'host_id', 'host_name', 'host_email', 'host_info', + 'desc_as_html', 'host_id', 'host_name', 'host_email', 'host_info', 'show_email', 'must_subscribe', 'communicate_participants', 'max_participants', 'min_participants', 'duration', 'desired_slot_nb', 'available_friday_evening', 'available_friday_night', @@ -244,7 +263,7 @@ class ExportSlots(SuperuserRequiredMixin, CSVWriteView): filename = "créneaux_interludes" headers = [ "Titre", "Début", "Salle", - "Ouverte aux inscriptions", "Affichée sur le planning", + "Ouverte aux inscriptions", "Affiché sur le planning", "Affiché sur l'activité", "Couleur", "Durée", "Durée activité", ] @@ -254,8 +273,8 @@ class ExportSlots(SuperuserRequiredMixin, CSVWriteView): for slot in slots: rows.append([ str(slot), slot.start, slot.room, - slot.subscribing_open, slot.on_planning, - Colors(slot.color).name, slot.duration, slot.activity.duration , + slot.subscribing_open, slot.on_planning, slot.on_activity, + Colors(slot.color).name, slot.duration, slot.activity.duration, ]) return rows diff --git a/home/admin.py b/home/admin.py index cdf56a9402907abea2c16848666e331e2bbaabe1..8e9e62d0229fed35f2e1909671a1bcc3da060aed 100644 --- a/home/admin.py +++ b/home/admin.py @@ -19,7 +19,7 @@ class ActivityModelAdmin(ExportCsvMixin, admin.ModelAdmin): list_editable = ("display",) fields = ( "title", "display", - ("host_name", "host_email"), + ("host_name", "host_email"), "show_email", "host_info", "act_type", "game_type", "description", "desc_as_html", @@ -46,7 +46,7 @@ class ActivityModelAdmin(ExportCsvMixin, admin.ModelAdmin): # The key is "host_id" but listed as "host" in auto-found field names # which leads to an error... 'id', 'display', 'title', 'act_type', 'game_type', 'description', - 'desc_as_html', 'host_id', 'host_name', 'host_email', 'host_info', + 'desc_as_html', 'host_id', 'host_name', 'host_email', 'show_email', 'host_info', 'must_subscribe', 'communicate_participants', 'max_participants', 'min_participants', 'duration', 'desired_slot_nb', 'available_friday_evening', 'available_friday_night', @@ -61,9 +61,14 @@ class ActivityModelAdmin(ExportCsvMixin, admin.ModelAdmin): class SlotModelAdmin(ExportCsvMixin, admin.ModelAdmin): """option d'affichage des créneaux dans la vue d'admin""" filename = "export_slots.csv" - list_display = ("__str__", "start", "room", "subscribing_open", "on_planning",) - list_filter = ("subscribing_open", "on_planning", "activity__display",) - list_editable = ("subscribing_open", "on_planning",) + csv_export_fields = ( + "activity_id", "title", + "start", "duration", "room", + "on_planning", "on_activity", "color", + ) + list_display = ("__str__", "start", "room", "subscribing_open", "on_planning", "on_activity",) + list_filter = ("subscribing_open", "on_planning", "on_activity", "activity__display",) + list_editable = ("subscribing_open", "on_planning", "on_activity",) ordering = ("activity", "title", "start",) diff --git a/home/forms.py b/home/forms.py index 862692993f5c4bb97b9a5a2681df6849281b4960..34b6609c22a343683d24e59d2ed7a724c0caa22d 100644 --- a/home/forms.py +++ b/home/forms.py @@ -66,7 +66,7 @@ class ActivitySubmissionForm(FormRenderMixin, forms.ModelForm): fields = ( "title", "act_type", "game_type", "description", - "host_info", + "host_name", "host_email", "host_info", "must_subscribe", "communicate_participants", "max_participants", "min_participants", @@ -98,12 +98,10 @@ class ActivitySubmissionForm(FormRenderMixin, forms.ModelForm): ) return cleaned_data - def save(self, user, *args, commit=True, **kwargs): + def save(self, *args, commit=True, **kwargs): """Enregistre l'activité dans la base de données""" activity = models.ActivityModel( **self.cleaned_data, - host=user, host_email=user.email, - host_name=(user.first_name + user.last_name) ) if commit: activity.save() diff --git a/home/migrations/0001_initial.py b/home/migrations/0001_initial.py index 3f541a2385ebb3c5890ab4e15fea429f8dc856d6..d32f6059365f09b7ba8e0e00f74ec185b968f4de 100644 --- a/home/migrations/0001_initial.py +++ b/home/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.7 on 2021-09-13 17:01 +# Generated by Django 3.2.7 on 2021-10-05 18:45 from django.conf import settings from django.db import migrations, models @@ -20,6 +20,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('display', models.BooleanField(default=False, help_text="Si vrai, s'affiche sur la page activités", verbose_name='afficher dans la liste')), + ('show_email', models.BooleanField(default=True, help_text="Si l'affichage d'email global et cette case sont vrai, affiche l'email de l'orga", verbose_name="afficher l'email de l'orga")), ('title', models.CharField(max_length=200, verbose_name='Titre')), ('act_type', models.CharField(choices=[('1 partie', 'Une partie'), ('2+ parties', 'Quelques parties'), ('Tournoi', 'Tournoi'), ('freeplay', 'Freeplay'), ('other', 'Autre')], max_length=12, verbose_name="Type d'activité")), ('game_type', models.CharField(choices=[('jeu cartes', 'Jeu de cartes'), ('jeu plateau', 'Jeu de société'), ('table RPG', 'Jeu de rôle sur table'), ('large RPG', 'Jeu de rôle grandeur nature'), ('videogame', 'Jeu vidéo'), ('partygame', 'Party game'), ('puzzle', 'Puzzle ou analogue'), ('secret roles', 'Jeu à rôles secrets'), ('coop', 'Jeu coopératif'), ('other', 'Autre')], max_length=12, verbose_name='Type de jeu')), @@ -60,9 +61,10 @@ class Migration(migrations.Migration): ('start', models.DateTimeField(verbose_name='début')), ('duration', models.DurationField(blank=True, help_text="Format 00:00:00. Laisser vide pour prendre la durée de l'activité correspondante", null=True, verbose_name='durée')), ('room', models.CharField(blank=True, max_length=100, null=True, verbose_name='salle')), - ('on_planning', models.BooleanField(default=False, help_text='Nécessite de salle et heure de début non vide', verbose_name='afficher sur le planning')), + ('on_planning', models.BooleanField(default=True, verbose_name='afficher sur le planning')), + ('on_activity', models.BooleanField(default=True, verbose_name="afficher dans la description de l'activité")), ('subscribing_open', models.BooleanField(default=False, help_text="Si vrai, apparaît dans la liste du formulaire d'inscription", verbose_name='ouvert aux inscriptions')), - ('color', models.CharField(choices=[('a', 'Rouge'), ('b', 'Orange'), ('c', 'Jaune'), ('d', 'Vert'), ('e', 'Bleu'), ('f', 'Bleu foncé'), ('g', 'Noir')], default='f', help_text='La légende des couleurs est modifiable dans les paramètres', max_length=1, verbose_name='Couleur')), + ('color', models.CharField(choices=[('a', 'Rouge'), ('b', 'Orange'), ('c', 'Jaune'), ('d', 'Vert'), ('e', 'Bleu'), ('f', 'Bleu foncé'), ('g', 'Noir')], default='a', help_text='La légende des couleurs est modifiable dans les paramètres', max_length=1, verbose_name='Couleur')), ('activity', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='home.activitymodel', verbose_name='Activité')), ], options={ diff --git a/home/models.py b/home/models.py index efe6208abbb4d2ec9aec7decf9301196872c44f3..f9b5bb29e414bd9e9f91934af461960f1d55d6bf 100644 --- a/home/models.py +++ b/home/models.py @@ -54,6 +54,10 @@ class ActivityModel(models.Model): display = models.BooleanField("afficher dans la liste", default=False, help_text="Si vrai, s'affiche sur la page activités" ) + show_email = models.BooleanField("afficher l'email de l'orga", default=True, + help_text="Si l'affichage d'email global et cette case sont vrai, affiche l'email de l'orga" + ) + title = models.CharField("Titre", max_length=200) @@ -167,15 +171,9 @@ class ActivityModel(models.Model): @property def pretty_type(self) -> str: - type = self.Types(self.act_type).label - return type - # status = self.Status(self.status) - # status_repr = "présentiel ou distanciel" - # if status == self.Status.DISTANT: - # status_repr = "distanciel" - # elif status == self.Status.PRESENT: - # status_repr = "présentiel" - # return "{} ({})".format(type, status_repr) + type = self.ActivityTypes(self.act_type).label + game = self.GameTypes(self.game_type).label + return "{}, {}".format(game, type.lower()) @property def slug(self) -> str: @@ -185,7 +183,7 @@ class ActivityModel(models.Model): @property def slots(self): """Returns a list of slots related to self""" - return SlotModel.objects.filter(activity=self, on_planning=True).order_by("start") + return SlotModel.objects.filter(activity=self, on_activity=True).order_by("start") def __str__(self): return self.title @@ -214,14 +212,16 @@ class SlotModel(models.Model): ) room = models.CharField("salle", max_length=100, null=True, blank=True) on_planning = models.BooleanField( - "afficher sur le planning", default=False, - help_text="Nécessite de salle et heure de début non vide", + "afficher sur le planning", default=True, + ) + on_activity = models.BooleanField( + "afficher dans la description de l'activité", default=True, ) subscribing_open = models.BooleanField("ouvert aux inscriptions", default=False, help_text="Si vrai, apparaît dans la liste du formulaire d'inscription" ) color = models.CharField( - "Couleur", choices=Colors.choices, max_length=1, default=Colors.DARK_BLUE, + "Couleur", choices=Colors.choices, max_length=1, default=Colors.RED, help_text="La légende des couleurs est modifiable dans les paramètres" ) diff --git a/home/static/css/style.css b/home/static/css/style.css index e7d4bf6cf2eef6235ad3680e532935543094f802..b7740e2f60e90130917dcb70c01f230be375ded8 100644 --- a/home/static/css/style.css +++ b/home/static/css/style.css @@ -98,7 +98,7 @@ header #head_main_infos { div.easter_egg { display: inline-block; } - + #circle { -webkit-clip-path: circle(50% at 50% 50%); clip-path: circle(50% at 50% 50%) @@ -135,6 +135,10 @@ nav a:hover { background-color: var(--color_bg_3); transition-duration: 0.5s; } +nav a:focus { + background-color: var(--color_bg_3); +} + nav a.current { background-color: var(--color_bg_1); @@ -224,6 +228,10 @@ main p { strong { font-weight: bold; } +.underline { + text-decoration: underline; +} + main a:link { text-decoration: underline; diff --git a/home/static/imgs/logo_grey.png b/home/static/imgs/logo_grey.png new file mode 100644 index 0000000000000000000000000000000000000000..8bef669ccd2f5d69a2fdf0592458cc772e68ce6c Binary files /dev/null and b/home/static/imgs/logo_grey.png differ diff --git a/home/static/imgs/logointerludes.png b/home/static/imgs/logointerludes.png new file mode 100644 index 0000000000000000000000000000000000000000..5a1413de644923a2d334135b8f5ef5320afc6914 Binary files /dev/null and b/home/static/imgs/logointerludes.png differ diff --git a/home/templates/activites.html b/home/templates/activites.html index ae149ed2d3799ce1b311046f18cf525986e2e941..f0086ba78b2a5f803ea33c1fcb01777b1e34b20e 100644 --- a/home/templates/activites.html +++ b/home/templates/activites.html @@ -23,7 +23,7 @@ <h2>Activités</h2> <p>Durant tout l'événement, des jeux seront en libre-service et des tables disponibles pour jouer. - Certaines activités ne pourront se faire qu'avec inscription au vue d'un nombre de places limité. + Certaines activités ne pourront se faire qu'avec inscription au vue d'une préparation en amont ou d'un nombre de places limité. </p> {% if settings.activity_submission_form %} <p>Vous pouver proposer une activité en remplissant <a href="{{ settings.activity_submission_form }}">ce formulaire</a>.</p> @@ -46,11 +46,14 @@ {% if activity.host_name %} <dt>Orga :</dt><dd>{{ activity.host_name }}</dd> {% endif %} + {% if settings.show_host_emails and activity.show_email %} + <dt>Contact :</dt><dd><a href="mailto:{{ activity.host_email }}">{{ activity.host_email }}</a></dd> + {% endif %} <dt>Type :</dt><dd>{{ activity.pretty_type }}</dd> <dt>Places :</dt><dd>{{ activity.nb_participants }}</dd> - {% if activity.slots %} - <dt>Heure<!--/Lieu--> :</dt><dd>{% for slot in activity.slots %} - {{ slot.start|date:"l H:i" }}<!-- {{ slot.room }} -->{% if not forloop.last %},<br> {% endif %} + {% if activity.slots and settings.display_planning %} + <dt>Heure/Lieu :</dt><dd>{% for slot in activity.slots %} + {{ slot.start|date:"l H:i" }}{% if slot.room %} {{ slot.room }}{% endif %}{% if not forloop.last %},<br> {% endif %} {% endfor %} </dd> {% endif %} diff --git a/home/templates/activity_submission.html b/home/templates/activity_submission.html index f56ecd448cae847864999193182eab2048f328dd..c1ecb6076862bf22b7fcdc358988d902b58e9a59 100644 --- a/home/templates/activity_submission.html +++ b/home/templates/activity_submission.html @@ -11,23 +11,38 @@ <form method="post" action="{% url 'activity_submission' %}"> {% csrf_token %} + <ul class="messagelist"> + <li class="info"> + Les informations publiques (qui apparaîtrons sur la page <a href="{% url 'activites' %}">activites</a>) sont + celles <span class="underline">soulignées</span>.<br> + Les autres ne serons vues que par les orgas. + </li> + </ul> + <table> - <tr><td><strong>Titre :</strong></td><td> {{ form.title }}</td></tr> - <tr><td><strong>Type d'activité :</strong></td><td> {{ form.act_type }}</td></tr> - <tr><td><strong>Type de jeu :</strong></td><td> {{ form.game_type }}</td></tr> + <tr><td><strong class="underline">Titre :</strong></td><td> {{ form.title }}</td></tr> + <tr><td><strong class="underline">Type d'activité :</strong></td><td> {{ form.act_type }}</td></tr> + <tr><td><strong class="underline">Type de jeu :</strong></td><td> {{ form.game_type }}</td></tr> </table> - <p><strong>Description :</strong> ce texte sera affiché sur la page + <p><strong class="underline">Description :</strong> ce texte sera affiché sur la page <a href="{% url 'activites' %}">activités</a> pour présenter votre activité. </p> {{ form.description }} <h3>Organisateurs</h3> + <table> + <tr><td><strong class="underline">Nom :</strong></td><td> {{ form.host_name }}</td></tr> + <tr><td><strong class="underline">Email :</strong></td><td> {{ form.host_email }}</td></tr> + <tr><td><strong>Compte associé : </strong></td><td> {{ request.user.email }}</td></tr> + </table> + <p> L'email de votre compte sera le principal moyen de contact. - Vous pouvez spécifiez d'autre moyen de contact ci-dessous, ainsi que d'autres - organisateurs si vous êtes plusieurs + Si vous ne souhaitez pas qu'il soit affiché, précisez le ci-dessous. + Vous pouvez également spécifier d'autres moyens de contact, ainsi que d'autres + organisateurs si vous êtes plusieurs. </p> {{ form.host_info }} @@ -35,18 +50,18 @@ <h3>Participants et inscription</h3> <table> - <tr><td><strong>Nécessite une inscription :</strong></td><td> {{ form.must_subscribe }}</td></tr> + <tr><td><strong class="underline">Nécessite une inscription :</strong></td><td> {{ form.must_subscribe }}</td></tr> <tr><td><strong>Me communiquer la liste des participants à l'avance :</strong></td><td> {{ form.communicate_participants }}</td></tr> - <tr><td><strong>Nombre max de participants :</strong></td><td> {{ form.max_participants }} (mettez 0 pour illimité)</td></tr> + <tr><td><strong class="underline">Nombre max de participants :</strong></td><td> {{ form.max_participants }} (mettez 0 pour illimité)</td></tr> {% if form.max_participants.errors %}<tr><td></td><td>{{ form.max_participants.errors }}</td></tr>{% endif %} - <tr><td><strong>Nombre min de participants :</strong></td><td> {{ form.min_participants }}</td></tr> + <tr><td><strong class="underline">Nombre min de participants :</strong></td><td> {{ form.min_participants }}</td></tr> {% if form.min_participants.errors %}<tr><td></td><td>{{ form.min_participants.errors }}</td></tr>{% endif %} </table> <h3>Durée et crénaux</h3> <table> - <tr><td><strong>Durée approximative :</strong></td><td> {{ form.duration }} (format hh:mm:ss)</td></tr> + <tr><td><strong class="underline">Durée approximative :</strong></td><td> {{ form.duration }} (format hh:mm:ss)</td></tr> {% if form.duration.errors %}<tr><td></td><td>{{ form.duration.errors }}</td></tr>{% endif %} <tr><td><strong>Nombre de crénaux souhaités :</strong></td><td> {{ form.desired_slot_nb }}</td></tr> {% if form.desired_slot_nb.errors %}<tr><td></td><td>{{ form.desired_slot_nb.errors }}</td></tr>{% endif %} diff --git a/home/templates/base.html b/home/templates/base.html index 1a93ed3254cc408b668f2a3252a0fee988306070..8d732a9a4c630c5faa6a44eb0cd635126ee77599 100644 --- a/home/templates/base.html +++ b/home/templates/base.html @@ -60,23 +60,23 @@ Activités </a> <a href="{% url 'FAQ' %}" rel="text/html" - class="{% block nav_faq %}{% endblock %} "> + class="{% block nav_faq %}{% endblock %}"> FAQ </a> {% if request.user.is_authenticated %} <a href="{% url 'profile' %}" - class="{% block nav_profile %}{% endblock %} "> + class="{% block nav_profile %}{% endblock %}"> Mon compte </a> {% else %} <a href="{% url 'accounts:login' %}" - class="{% block nav_login %}{% endblock %} "> + class="{% block nav_login %}{% endblock %}"> Connexion </a> {% endif %} {% if user.is_superuser %} <a href="{% url 'admin_pages:index' %}" - class="{% block nav_admin %}{% endblock %} "> + class="{% block nav_admin %}{% endblock %}"> Administration </a> {% endif %} diff --git a/home/templates/faq.html b/home/templates/faq.html index 7bdf7eb0a77d5b0852df2f77d0d738ff45219e97..c3fa1848e6c259241bdf05b8c057104b0f75f91d 100644 --- a/home/templates/faq.html +++ b/home/templates/faq.html @@ -5,11 +5,13 @@ {% block "content" %} <h2>Quelles seront les mesures de protection sanitaire ?</h2> - <p>Les mesures définitives vous seront communiquées à l'arrivée à l'événement. Elles inclueront probablement :</p> + <p>Les mesures définitives vous seront communiquées à l'arrivée à l'événement. Elles incluront probablement :</p> <ul> + <li>Contrôle des passes sanitaires chaque jour</li> <li>Port du masque obligatoire en permanence</li> - <li>Lavage de main entre chaque jeu/activité</li> - <li>Pause aération des salles régulières</li> + <li>Lavage de main entre chaque jeu/activité conseillé</li> + <li>Des QR Codes à scanner sur chaque table (pour garder trace des cas contacts si une personne est déclarée positive)</li> + <li>Salles aérées en permanence et joueur·ses invité·es à se rendre dehors si le taux de CO2 devient trop élevé</li> </ul> @@ -48,7 +50,7 @@ <div id="transport-metro-icon"> <img src="{% static 'imgs/ratp/metro-7.svg' %}" alt="Métro 7"> </div> - <span id="transport-metro-stop">Place Monge</span> + <span id="transport-metro-stop">Censier Daubenton</span> <div id="transport-rer-icon"> <img src="{% static 'imgs/ratp/rer-B.svg' %}" alt="RER B"> diff --git a/home/templates/home.html b/home/templates/home.html index 41332b97b0d267b303780b3d5bd60e9c7dc05a76..fe066d899a4fe555a404d20ce81085b7ec9f7579 100644 --- a/home/templates/home.html +++ b/home/templates/home.html @@ -62,7 +62,10 @@ <h2>Liens divers</h2> <ul> - <li>Le code source de ce site est sur <a href="https://git.eleves.ens.fr/dlesbre/site-interludes">gitlab</a>.</li> + <li>Le <a href="https://jeux.cof.ens.fr/">site du club jeux</a></li> + <li>Le <a href="https://cof.ens.fr">site du COF</a>.</li> + <li>Le <a href="https://wiki.crans.org/VieBdl/InterLudes">Le wiki de Paris-Saclay</a> qui recense les visuels, sites webs et photos des interludes passées.</li> + <li>Le code source de ce site est sur <a href="https://git.eleves.ens.fr/dlesbre/site-interludes">gitlab</a> et <a href="https://github.com/dlesbre/site-interludes">github</a>.</li> <li>Un historique des interludes avec leurs visuels, site webs et photos est sur le <a href="https://wiki.crans.org/VieBdl/InterLudes">wiki de Paris-Saclay</a>.</li> </ul> {% endblock %} diff --git a/home/urls.py b/home/urls.py index 8fd2ddd7de7bc03e5b28d595e261abd8134318a7..57085fe82e1a5205fda17901a0190e735f9bcbf5 100644 --- a/home/urls.py +++ b/home/urls.py @@ -15,14 +15,14 @@ urlpatterns = [ path('activites/', views.ActivityView.as_view(), name = 'activites'), path('activites/nouvelle/', views.ActivitySubmissionView.as_view(), name = 'activity_submission'), path('faq/', views.FAQView.as_view(), name = 'FAQ'), - path("profile/", views.ProfileView.as_view(), name="profile"), + path("profil/", views.ProfileView.as_view(), name="profile"), path('favicon.ico', RedirectView.as_view(url='/static/imgs/favicon.ico')), path( 'sitemap.xml', sitemap, {'sitemaps': sitemaps}, name='django.contrib.sitemaps.views.sitemap' ), path('admin_pages/', include(('admin_pages.urls', 'admin_pages'), namespace="admin_pages")), - path('accounts/', include("accounts.urls")), + path('comptes/', include("accounts.urls")), ] if settings.DEBUG: diff --git a/home/views.py b/home/views.py index 86bc726059a3c9aa094d52700cb506c7c9325020..f93c53d8c63b727520f67160063488cf5cffd43a 100644 --- a/home/views.py +++ b/home/views.py @@ -51,7 +51,7 @@ class ActivityView(TemplateView): class FAQView(TemplateView): """Vue pour la FAQ""" - template_name = "faq-distanciel.html" + template_name = "faq.html" # ============================== @@ -92,7 +92,7 @@ class RegisterSignIn(TemplateView): class RegisterUpdateView(LoginRequiredMixin, TemplateView): """Vue pour s'inscrire et modifier son inscription""" - template_name = "inscription/form-distanciel.html" + template_name = "inscription/form.html" form_class = InscriptionForm formset_class = formset_factory(form=ActivityForm, extra=3, formset=BaseActivityFormSet) success_url = reverse_lazy("profile") @@ -178,6 +178,15 @@ class ActivitySubmissionView(LoginRequiredMixin, FormView): settings = SiteSettings.load() return settings.activity_submission_open + def get_initial(self): + init = super().get_initial() + user = self.request.user + init.update({ + "host_name": "{} {}".format(user.first_name, user.last_name), + "host_email": user.email, + }) + return init + def not_open(self, request): """Appelé quand le formulaire est désactivé""" messages.error(request, "La soumission d'activité est desactivée") @@ -193,11 +202,11 @@ class ActivitySubmissionView(LoginRequiredMixin, FormView): return self.not_open(request) form = self.form_class(request.POST) if not form.is_valid(): - context = self.get_context_data + context = self.get_context_data() context["form"] = form return render(request, self.template_name, context) - form.save(user=request.user) + form.save() messages.success(request, "Votre activité a bien été enregistrée. Elle sera affichée sur le site après relecture par les admins.") return redirect(self.success_url, permanent=False) diff --git a/site_settings/constants.py b/site_settings/constants.py index 0091d7125376bcd276ae3859203a9be9eadde9b3..b69adf4317c25fcf17e4bdfc87f833a47ffcc3e6 100644 --- a/site_settings/constants.py +++ b/site_settings/constants.py @@ -1,10 +1,10 @@ # The website version number -WEBSITE_VERSION = "1.2.8" -WEBSITE_VERSION_DATE = "2021-05-06" +WEBSITE_VERSION = "2.0.0-beta" +WEBSITE_VERSION_DATE = "2021-10-05" WEBSITE_FULL_VERSION = "{} - {}".format( WEBSITE_VERSION, WEBSITE_VERSION_DATE ) # Update this to force reload of cached css -CSS_VERSION = "1.1" +CSS_VERSION = "1.0" diff --git a/site_settings/migrations/0001_initial.py b/site_settings/migrations/0001_initial.py index d98c22f98bcb191bfe798847a165101ac7b36c79..8eef33a187cf750c6589ea14ac62df8dad8704f8 100644 --- a/site_settings/migrations/0001_initial.py +++ b/site_settings/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.2.7 on 2021-09-13 17:01 +# Generated by Django 3.2.7 on 2021-10-05 18:45 from django.db import migrations, models import site_settings.models @@ -22,6 +22,7 @@ class Migration(migrations.Migration): ('registrations_open', models.BooleanField(default=True, verbose_name='Ouvrir la création de compte')), ('inscriptions_open', models.BooleanField(default=False, verbose_name='Ouvrir les inscriptions')), ('activity_submission_open', models.BooleanField(default=False, help_text='Permet de proposer une activité via le formulaire dédié', verbose_name="Ouvrir l'ajout d'activité")), + ('show_host_emails', models.BooleanField(default=False, help_text='Ces mail sont affichés sur la page activités pour que les gens puissent les contacter', verbose_name="Afficher les mails des orgas d'activités")), ('inscriptions_start', models.DateTimeField(blank=True, help_text="Cette date n'est qu'informative. Les inscription s'ouvrent via la checkbox uniquement", null=True, verbose_name='Ouverture des inscriptions')), ('inscriptions_end', models.DateTimeField(blank=True, help_text="Cette date n'est qu'informative. Les inscription se ferment via la checkbox uniquement", null=True, verbose_name='Fermeture des inscriptions')), ('display_planning', models.BooleanField(default=False, verbose_name='Afficher le planning')), diff --git a/site_settings/models.py b/site_settings/models.py index 119695dc492001bf560ebb98a0f9ce995ebeca73..9f5e30ff3fbb92da119abc1515b7ecdd8a98ec00 100644 --- a/site_settings/models.py +++ b/site_settings/models.py @@ -77,6 +77,11 @@ class SiteSettings(SingletonModel): "Ouvrir l'ajout d'activité", default=False, help_text="Permet de proposer une activité via le formulaire dédié" ) + show_host_emails = models.BooleanField( + "Afficher les mails des orgas d'activités", default=False, + help_text="Ces mail sont affichés sur la page activités pour que les gens puissent les contacter", + ) + inscriptions_start = models.DateTimeField("Ouverture des inscriptions", blank=True, null=True, @@ -98,8 +103,6 @@ class SiteSettings(SingletonModel): help_text="Suppose que l'allocation des activités a été effectuée." ) - - discord_link = models.CharField( "Lien du serveur discord", max_length=200, blank=True, null=True )