diff --git a/inventory/admin.py b/inventory/admin.py index 787b95d..e676d9a 100644 --- a/inventory/admin.py +++ b/inventory/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin -from .models import Category, Tag, Game +from .models import Category, Tag, Game, GameComment admin.site.register(Category) admin.site.register(Tag) admin.site.register(Game) +admin.site.register(GameComment) diff --git a/inventory/migrations/0002_auto_20201212_2233.py b/inventory/migrations/0002_auto_20201212_2233.py new file mode 100644 index 0000000..bc80903 --- /dev/null +++ b/inventory/migrations/0002_auto_20201212_2233.py @@ -0,0 +1,76 @@ +# Generated by Django 3.1.2 on 2020-12-12 21:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('inventory', '0001_initial'), + ] + + operations = [ + migrations.AlterModelOptions( + name='category', + options={'ordering': ['name'], 'verbose_name': 'catégorie'}, + ), + migrations.AlterModelOptions( + name='game', + options={'ordering': ['title'], 'verbose_name': 'jeu', 'verbose_name_plural': 'jeux'}, + ), + migrations.AlterModelOptions( + name='tag', + options={'ordering': ['name']}, + ), + migrations.AddField( + model_name='game', + name='illustrator', + field=models.CharField(blank=True, max_length=256, verbose_name='illustrateur·trice'), + ), + migrations.AddField( + model_name='game', + name='missing_elements', + field=models.TextField(blank=True, verbose_name='pièces manquantes'), + ), + migrations.AddField( + model_name='game', + name='nb_player_max', + field=models.PositiveSmallIntegerField(default=20, verbose_name='nombre de joueur·se·s maximum'), + preserve_default=False, + ), + migrations.AddField( + model_name='game', + name='nb_player_min', + field=models.PositiveSmallIntegerField(default=2, verbose_name='nombre de joueur·se·s minimum'), + preserve_default=False, + ), + migrations.AlterField( + model_name='game', + name='duration', + field=models.CharField(blank=True, max_length=256, verbose_name='durée de partie'), + ), + migrations.AlterField( + model_name='game', + name='player_range', + field=models.CharField(blank=True, help_text='Affichage personnalisé pour le nombre de joueur·se·s', max_length=256, verbose_name='nombre de joueur·se·s'), + ), + migrations.CreateModel( + name='GameComment', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('text', models.TextField(verbose_name='texte')), + ('created_on', models.DateTimeField(auto_now_add=True, verbose_name='date de publication')), + ('modified_on', models.DateTimeField(auto_now=True, verbose_name='date de modification')), + ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='auteur·ice')), + ('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='inventory.game', verbose_name='jeu')), + ], + options={ + 'verbose_name': 'commentaire sur un jeu', + 'verbose_name_plural': 'commentaires sur des jeux', + 'ordering': ['created_on'], + }, + ), + ] diff --git a/inventory/models.py b/inventory/models.py index ccb24c0..2b40a05 100644 --- a/inventory/models.py +++ b/inventory/models.py @@ -1,5 +1,7 @@ from django.db import models from django.urls import reverse +from django.contrib.auth.models import User +from django.core.exceptions import ValidationError from autoslug import AutoSlugField @@ -8,6 +10,7 @@ class Category(models.Model): slug = AutoSlugField(populate_from="name", unique=True) class Meta: + ordering = ["name"] verbose_name = "catégorie" def __str__(self): @@ -21,6 +24,9 @@ class Tag(models.Model): name = models.CharField(max_length=256, verbose_name="nom") slug = AutoSlugField(populate_from="name", unique=True) + class Meta: + ordering = ["name"] + def __str__(self): return self.name @@ -31,27 +37,83 @@ class Tag(models.Model): class Game(models.Model): title = models.CharField(verbose_name="titre", max_length=256) slug = AutoSlugField(populate_from="title", unique=True) - player_range = models.CharField( - max_length=256, verbose_name="nombre de joueur·se·s" + nb_player_min = models.PositiveSmallIntegerField( + verbose_name="nombre de joueur·se·s minimum" + ) + nb_player_max = models.PositiveSmallIntegerField( + verbose_name="nombre de joueur·se·s maximum" + ) + player_range = models.CharField( + max_length=256, + blank=True, + help_text="Affichage personnalisé pour le nombre de joueur·se·s", + verbose_name="nombre de joueur·se·s", + ) + duration = models.CharField( + max_length=256, blank=True, verbose_name="durée de partie" ) - duration = models.CharField(max_length=256, verbose_name="durée de partie") - editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur") game_designer = models.CharField( max_length=256, blank=True, verbose_name="game designer" ) + illustrator = models.CharField( + max_length=256, blank=True, verbose_name="illustrateur·trice" + ) + editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur") description = models.TextField(blank=True, verbose_name="description") category = models.ForeignKey( Category, on_delete=models.RESTRICT, verbose_name="catégorie" ) tags = models.ManyToManyField(Tag, blank=True, verbose_name="tags") image = models.ImageField(upload_to="game_img/", blank=True, verbose_name="image") + missing_elements = models.TextField(blank=True, verbose_name="pièces manquantes") class Meta: + ordering = ["title"] verbose_name = "jeu" verbose_name_plural = "jeux" def __str__(self): return self.title + def clean(self): + if self.nb_player_min > self.nb_player_max: + raise ValidationError( + { + "nb_player_max": "Le nombre de joueur·se·s maximum doit être supérieur au nombre de joueurs minimum" + } + ) + + def get_player_range(self): + if self.player_range: + return self.player_range + elif self.nb_player_min != self.nb_player_max: + return "{} à {} joueur·se·s".format(self.nb_player_min, self.nb_player_max) + else: + return "{} joueur·se·s".format(self.nb_player_min) + def get_absolute_url(self): return reverse("inventory:game", args=(self.slug,)) + + +class GameComment(models.Model): + game = models.ForeignKey( + Game, on_delete=models.CASCADE, related_name="comments", verbose_name="jeu" + ) + author = models.ForeignKey( + User, on_delete=models.CASCADE, verbose_name="auteur·ice" + ) + text = models.TextField(verbose_name="texte") + created_on = models.DateTimeField( + auto_now_add=True, verbose_name="date de publication" + ) + modified_on = models.DateTimeField( + auto_now=True, verbose_name="date de modification" + ) + + class Meta: + ordering = ["created_on"] + verbose_name = "commentaire sur un jeu" + verbose_name_plural = "commentaires sur des jeux" + + def __str__(self): + return "({}) {}: {}".format(self.game, self.author, self.text) diff --git a/inventory/templates/inventory/category_list.html b/inventory/templates/inventory/category_list.html index 1eabbf2..302a512 100644 --- a/inventory/templates/inventory/category_list.html +++ b/inventory/templates/inventory/category_list.html @@ -6,7 +6,7 @@ Il y a {{ category_list|length }} catégorie{{ category_list|pluralize }} de jeux : {% endblock %} diff --git a/inventory/templates/inventory/game.html b/inventory/templates/inventory/game.html index 2268561..8ec94b4 100644 --- a/inventory/templates/inventory/game.html +++ b/inventory/templates/inventory/game.html @@ -12,8 +12,8 @@

{{ game.category }}


-

{{ game.player_range }}

-

{{ game.duration }} +

{{ game.get_player_range }}

+

{{ game.duration|default:"(Durée de jeu inconnue)" }}


{% for tag in game.tags.all %} @@ -23,10 +23,56 @@ {% endfor %}


-

{{ game.game_designer|default:"(Game designer inconnu)" }} +

{{ game.game_designer|default:"(Game designer inconnu·e)" }} +

{{ game.illustrator|default:"(Illustrateur·trice inconnu·e)" }}

{{ game.editor|default:"(Éditeur inconnu)" }}

-

{{ object.description }}

+

Description

+ {{ object.description|linebreaks }} + + {% if game.missing_elements %} +

Pièces manquantes

+

{{ game.missing_elements|linebreaksbr }}

+ {% endif %} + +

Commentaires et propositions de variantes

+ + {% if not edited_comment %} + {% if request.user.is_authenticated %} +
+ {% csrf_token %} + + +
+ {% else %} + Connectez-vous pour ajouter un commentaire. + {% endif %} + {% endif %} {% endblock %} diff --git a/inventory/templates/inventory/partials/category_item.html b/inventory/templates/inventory/partials/category_item.html new file mode 100644 index 0000000..52ecdab --- /dev/null +++ b/inventory/templates/inventory/partials/category_item.html @@ -0,0 +1,3 @@ +
  • + {{ category.name }} +
  • diff --git a/inventory/templates/inventory/partials/game_item.html b/inventory/templates/inventory/partials/game_item.html index b364bcc..b056560 100644 --- a/inventory/templates/inventory/partials/game_item.html +++ b/inventory/templates/inventory/partials/game_item.html @@ -1,15 +1,18 @@
  • - {{game.title}} + {{ game.title }}
    -

    {{ game.player_range }}

    +

    {{ game.get_player_range }}

    {{ game.duration }}

    {{ game.category }}

    {% for tag in game.tags.all %}

    {{ tag }}

    {% endfor %} {% if game.game_designer %} -

    {{ game.game_designer }} +

    {{ game.game_designer }}

    + {% endif %} + {% if game.illustrator %} +

    {{ game.illustrator }}

    {% endif %} {% if game.editor %}

    {{ game.editor }}

    diff --git a/inventory/templates/inventory/partials/pagination.html b/inventory/templates/inventory/partials/pagination.html new file mode 100644 index 0000000..a00b606 --- /dev/null +++ b/inventory/templates/inventory/partials/pagination.html @@ -0,0 +1,8 @@ +{% if page_obj.has_other_pages %} +
    +{% endif %} + diff --git a/inventory/templates/inventory/partials/tag_item.html b/inventory/templates/inventory/partials/tag_item.html new file mode 100644 index 0000000..95b5b35 --- /dev/null +++ b/inventory/templates/inventory/partials/tag_item.html @@ -0,0 +1,3 @@ +
  • + {{ tag.name }} +
  • diff --git a/inventory/templates/inventory/search.html b/inventory/templates/inventory/search.html index 44faa6e..c348a66 100644 --- a/inventory/templates/inventory/search.html +++ b/inventory/templates/inventory/search.html @@ -2,7 +2,7 @@ {% block "content" %}

    Recherche

    - @@ -15,25 +15,15 @@ {% if result.model_name == "game" %} {% include "./partials/game_item.html" with game=result.object %} {% elif result.model_name == "category" %} -
  • - {{ result.object.name }} -
  • + {% include "./partials/category_item.html" with category=result.object %} {% elif result.model_name == "tag" %} -
  • - {{ result.object.name }} -
  • + {% include "./partials/tag_item.html" with tag=result.object %} {% endif %} {% empty %}
  • Aucun résultat trouvé
  • {% endfor %} - {% if page_obj.has_previous or page_obj.has_next %} -
    - {% if page_obj.has_previous %}{% endif %}« Précédent{% if page_obj.has_previous %}{% endif %} - | - {% if page_obj.has_next %}{% endif %}Suivant »{% if page_obj.has_next %}{% endif %} -
    - {% endif %} + {% include "./partials/pagination.html" %} {% endif %} {% endblock %} diff --git a/inventory/templates/inventory/search_indexes/game.txt b/inventory/templates/inventory/search_indexes/game.txt index cf19c30..bd7e7f0 100644 --- a/inventory/templates/inventory/search_indexes/game.txt +++ b/inventory/templates/inventory/search_indexes/game.txt @@ -1,4 +1,5 @@ {{ object.title }} -{{ object.editor }} {{ object.game_designer }} +{{ object.illustrator }} +{{ object.editor }} {{ object.description }} diff --git a/inventory/templates/inventory/tag_list.html b/inventory/templates/inventory/tag_list.html index 950b414..74147b2 100644 --- a/inventory/templates/inventory/tag_list.html +++ b/inventory/templates/inventory/tag_list.html @@ -6,7 +6,7 @@ Il y a {{ tag_list|length }} tag{{ tag_list|pluralize }} dans la ludothèque : {% endblock %} diff --git a/inventory/urls.py b/inventory/urls.py index ce3a262..1411cfa 100644 --- a/inventory/urls.py +++ b/inventory/urls.py @@ -7,6 +7,8 @@ from .views import ( TagView, GameListView, GameView, + AddGameCommentView, + ModifyGameCommentView, InventorySearchView, ) @@ -20,5 +22,13 @@ urlpatterns = [ path("tag//", TagView.as_view(), name="tag"), path("game/", GameListView.as_view(), name="game_list"), path("game//", GameView.as_view(), name="game"), + path( + "game//add_comment", AddGameCommentView.as_view(), name="add_game_comment" + ), + path( + "game//modify_comment/", + ModifyGameCommentView.as_view(), + name="modify_game_comment", + ), path("search/", InventorySearchView.as_view(), name="search"), ] diff --git a/inventory/views.py b/inventory/views.py index 76d27c0..ae90c17 100644 --- a/inventory/views.py +++ b/inventory/views.py @@ -1,8 +1,20 @@ -from django.views.generic import TemplateView, ListView, DetailView +from django.views.generic import ( + TemplateView, + ListView, + DetailView, + RedirectView, +) +from django.views.generic.detail import SingleObjectMixin +from django.contrib.auth.mixins import LoginRequiredMixin +from django.urls import reverse +from django.shortcuts import redirect, get_object_or_404 +from django.contrib import messages +from django.http import Http404 +from django.core.exceptions import PermissionDenied from haystack.generic_views import SearchView from haystack.forms import SearchForm from haystack.query import SearchQuerySet -from .models import Category, Tag, Game +from .models import Category, Tag, Game, GameComment class InventoryView(TemplateView): @@ -45,3 +57,55 @@ class InventorySearchView(SearchView): def get_queryset(self): return SearchQuerySet().models(Category, Tag, Game) + + +class AddGameCommentView(LoginRequiredMixin, SingleObjectMixin, RedirectView): + model = Game + permanent = False + + def get_redirect_url(self, *args, **kwargs): + req_dict = self.request.POST + if "comment_text" in req_dict: + comment_text = req_dict["comment_text"] + + game = self.get_object() + game.comments.create(author=self.request.user, text=comment_text) + messages.success(self.request, "Commentaire ajouté") + else: + messages.error( + self.request, "Pas de texte pour le commentaire dans la requête" + ) + + return reverse("inventory:game", kwargs=kwargs) + + +class ModifyGameCommentView(LoginRequiredMixin, SingleObjectMixin, TemplateView): + model = Game + template_name = "inventory/game.html" + + def dispatch(self, *args, **kwargs): + comment_id = kwargs["comment_id"] + self.object = self.get_object() + self.comment = get_object_or_404(GameComment, id=comment_id) + if self.comment.game != self.object: + raise Http404() + if self.comment.author != self.request.user: + raise PermissionDenied() + return super().dispatch(*args, **kwargs) + + def post(self, *args, **kwargs): + req_dict = self.request.POST + if "comment_text" in req_dict: + self.comment.text = req_dict["comment_text"] + self.comment.save() + messages.success(self.request, "Commentaire modifié") + else: + messages.error( + self.request, "Pas de texte pour le commentaire dans la requête" + ) + return redirect("inventory:game", slug=kwargs["slug"]) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["edited_comment"] = self.comment + return context diff --git a/mainsite/scss/forms.scss b/mainsite/scss/forms.scss index 509c3cc..67093db 100644 --- a/mainsite/scss/forms.scss +++ b/mainsite/scss/forms.scss @@ -26,7 +26,7 @@ form { color: $help_text_color; } -input { +input, textarea { display: block; width: 100%; font: inherit; @@ -36,11 +36,13 @@ input { input[type="text"], input[type="email"], -input[type="password"], { +input[type="password"], +input[type="search"], +textarea { background-color: white; border: solid 1px $help_text_color; padding: 5px 10px; - border-radius: 3px; + border-radius: 5px; box-shadow: none; &:optional { @@ -56,6 +58,13 @@ input[type="password"], { } } +textarea { + font-family: $font_family; + font-size: 1em; + resize: vertical; + min-height: 120px; +} + input[type="checkbox"], input[type="radio"] { width: auto; @@ -99,9 +108,26 @@ select { form.search { flex-direction: row; - gap: 10px; + input[type="search"] { + border-radius: 5px 0 0 5px; + border-right: 0; + } button { margin: 0; + border-radius: 0 10px 10px 0; + } +} + +form.comment { + font-size: 0.7em; + textarea { + border-radius: 10px 10px 0 0; + border-bottom: none; + margin: 0; + } + button { + border-radius: 0 0 10px 10px; + margin: 0; } } diff --git a/mainsite/scss/header.scss b/mainsite/scss/header.scss index 4642875..b83708f 100644 --- a/mainsite/scss/header.scss +++ b/mainsite/scss/header.scss @@ -14,7 +14,7 @@ header { margin: 0; padding: 0 20px; color: $header_text_color; - font-size: $font_size; + font-size: 1em; } nav { @@ -31,12 +31,11 @@ header { border-radius: 0; color: $header_text_color; - font-size: $nav_font_size; text-decoration: none; &:hover { background-color: darken($header_bg_color, 10%); - color: $page_link_hover_color; + color: $page_link_color; } &.current { background-color: $header_border_color; @@ -44,11 +43,11 @@ header { &:focus { background-color: darken($header_bg_color, 10%); box-shadow: none; - color: $page_link_hover_color; + color: $page_link_color; } } .username { - font-size: 12pt; + font-size: 0.7em; } } diff --git a/mainsite/scss/mixins.scss b/mainsite/scss/mixins.scss index fc719d2..36750d7 100644 --- a/mainsite/scss/mixins.scss +++ b/mainsite/scss/mixins.scss @@ -3,7 +3,6 @@ padding: 10px; border: 1px solid $border_color; background-color: $bg_color; - color: $page_text_color; } @mixin error_box { @include box($error_box_color, $error_box_border_color); @@ -23,6 +22,7 @@ text-decoration: none; text-align: center; font-size: 100%; + color: $page_text_color; @include box(lighten($header_border_color, 40%), $header_border_color); diff --git a/mainsite/scss/params.scss b/mainsite/scss/params.scss index 32c6fdb..9c9bb01 100644 --- a/mainsite/scss/params.scss +++ b/mainsite/scss/params.scss @@ -1,7 +1,6 @@ $page_bg_color: #f6fbfd; $page_text_color: #250f2d; -$page_link_color: #2b153f; -$page_link_hover_color: #180c23; +$page_link_color: #1e464c; $page_width: 800px; $small_page_width: 500px; @@ -16,20 +15,18 @@ $header_bg_color: #6bb8c4; $header_text_color: #f6fbfd; $header_infos_font_family: "Kalam"; $header_border_color: #51808c; -$nav_font_size: 18pt; $footer_bg_color: $header_bg_color; -$footer_font_size: 12pt; $indexbar_bg_color_1: rgba($header_bg_color, 0.75); $indexbar_bg_color_2: rgba($header_bg_color, 0.6); $indexbar_text_color: darken($page_link_color, 15); -$info_box_color: #c9c8ff; +$info_box_color: #e0dfff; $info_box_border_color: darken($info_box_color, 20%); -$error_box_color: #ffcddd; +$error_box_color: #ffdfe9; $error_box_border_color: darken($error_box_color, 20%); -$success_box_color: #a4ffc4; -$success_box_border_color: darken($success_box_color, 40%); -$warning_box_color: #ffd45d; +$success_box_color: #ddffd8; +$success_box_border_color: darken($success_box_color, 20%); +$warning_box_color: #ffedbb; $warning_box_border_color: darken($warning_box_color, 20%); diff --git a/mainsite/scss/style.scss b/mainsite/scss/style.scss index 0cbf82e..55709e4 100644 --- a/mainsite/scss/style.scss +++ b/mainsite/scss/style.scss @@ -50,7 +50,7 @@ main { footer { background-color: $footer_bg_color; - font-size: $footer_font_size; + font-size: 0.7em; text-align: center; padding: 10px; } @@ -69,13 +69,23 @@ h1 { font-weight: bold; } +h2 { + font-size: 1.25em; + font-weight: bold; +} + +h3 { + font-size: 1em; + font-weight: bold; +} + a { - text-decoration: underline; + text-decoration: underline lighten($header_border_color, 40%); color: $page_link_color; border-radius: 3px; &:hover { - color: $page_link_hover_color; + text-decoration-color: $page_link_color; } } @@ -106,7 +116,7 @@ hr { button, .btn_row a { @include button; - margin: 10px 5px; + margin: 10px 0; p { margin: 0; @@ -277,37 +287,62 @@ iframe { } ul { - padding: 0 20px; + padding: 0; list-style-type: none; +} - li>a { - display: block; - text-decoration: none; - padding: 15px; - margin: 10px 5px; - border-radius: 10px; - border: 1px solid transparent; +li>a { + display: block; + padding: 15px; + margin: 10px 5px; + border-radius: 10px; + border: 1px solid transparent; + text-decoration: none; - &:hover { - border-color: $header_border_color; - background-color: lighten($header_border_color, 70%); - } - &:focus { - border-color: $header_border_color; - background-color: lighten($header_border_color, 70%); - box-shadow: 0 0 1.5px 1px $header_bg_color; - } + .title { + text-decoration: underline lighten($header_border_color, 40%); + } - .details { - font-size: 0.7em; - display: flex; - flex-wrap: wrap; - margin: 5px; - gap: 5px 20px; + .details { + font-size: 0.7em; + display: flex; + flex-wrap: wrap; + margin: 5px; + gap: 5px 20px; - p { - margin: 0; - } + p { + margin: 0; } } + + &:hover { + border-color: $header_border_color; + background-color: white; + + .title { + text-decoration-color: currentColor; + } + } + &:focus { + border-color: $header_border_color; + background-color: white; + box-shadow: 0 0 1.5px 1px $header_bg_color; + } +} + +li.comment { + @include box(white, $indexbar_bg_color_1); + margin: 1em 0; + font-size: 0.7em; + + .author { + font-weight: bold; + } + .date { + font-size: 0.7em; + } + + p { + margin: 0.5em; + } } diff --git a/mainsite/static/css/style.css b/mainsite/static/css/style.css index 23d8475..2c18d58 100644 --- a/mainsite/static/css/style.css +++ b/mainsite/static/css/style.css @@ -12,7 +12,7 @@ header { margin: 0; padding: 0 20px; color: #f6fbfd; - font-size: 16pt; } + font-size: 1em; } header nav { display: flex; justify-content: left; @@ -24,19 +24,18 @@ header { padding: 10px 20px; border-radius: 0; color: #f6fbfd; - font-size: 18pt; text-decoration: none; } header a:hover { background-color: #48a6b4; - color: #180c23; } + color: #1e464c; } header a.current { background-color: #51808c; } header a:focus { background-color: #48a6b4; box-shadow: none; - color: #180c23; } + color: #1e464c; } header .username { - font-size: 12pt; } + font-size: 0.7em; } form { display: flex; @@ -50,9 +49,8 @@ form { form .errorlist li { border-radius: 10px; padding: 10px; - border: 1px solid #ff6798; - background-color: #ffcddd; - color: #250f2d; + border: 1px solid #ff79a3; + background-color: #ffdfe9; margin-bottom: 10px; } form p { margin: 5px 0; @@ -62,7 +60,7 @@ form { font-size: 0.7em; color: rgba(37, 15, 45, 0.65); } -input { +input, textarea { display: block; width: 100%; font: inherit; @@ -71,26 +69,40 @@ input { input[type="text"], input[type="email"], -input[type="password"] { +input[type="password"], +input[type="search"], +textarea { background-color: white; border: solid 1px rgba(37, 15, 45, 0.65); padding: 5px 10px; - border-radius: 3px; + border-radius: 5px; box-shadow: none; } input[type="text"]:optional, input[type="email"]:optional, - input[type="password"]:optional { + input[type="password"]:optional, + input[type="search"]:optional, + textarea:optional { border-color: rgba(37, 15, 45, 0.4); } input[type="text"]:focus, input[type="email"]:focus, - input[type="password"]:focus { + input[type="password"]:focus, + input[type="search"]:focus, + textarea:focus { border-color: #6bb8c4; box-shadow: 0 0 1.5px 1px #6bb8c4; } input[type="text"]:-moz-ui-invalid, input[type="email"]:-moz-ui-invalid, - input[type="password"]:-moz-ui-invalid { - border-color: #ff6798; - box-shadow: 0 0 1.5px 1px #ff6798; } + input[type="password"]:-moz-ui-invalid, + input[type="search"]:-moz-ui-invalid, + textarea:-moz-ui-invalid { + border-color: #ff79a3; + box-shadow: 0 0 1.5px 1px #ff79a3; } + +textarea { + font-family: "Open Sans"; + font-size: 1em; + resize: vertical; + min-height: 120px; } input[type="checkbox"], input[type="radio"] { @@ -102,11 +114,11 @@ input[type="submit"] { text-decoration: none; text-align: center; font-size: 100%; + color: #250f2d; border-radius: 10px; padding: 10px; border: 1px solid #51808c; - background-color: #c9dbe0; - color: #250f2d; } + background-color: #c9dbe0; } input[type="submit"]:hover { background-color: #a9c6cd; } input[type="submit"]:focus { @@ -120,11 +132,11 @@ select { text-decoration: none; text-align: center; font-size: 100%; + color: #250f2d; border-radius: 10px; padding: 10px; border: 1px solid #51808c; background-color: #c9dbe0; - color: #250f2d; width: 100%; font-size: 0.9em; margin: 0; @@ -149,12 +161,25 @@ select { .error_field { border-radius: 10px; - background-color: rgba(255, 205, 221, 0.4); } + background-color: rgba(255, 223, 233, 0.4); } form.search { - flex-direction: row; - gap: 10px; } + flex-direction: row; } + form.search input[type="search"] { + border-radius: 5px 0 0 5px; + border-right: 0; } form.search button { + margin: 0; + border-radius: 0 10px 10px 0; } + +form.comment { + font-size: 0.7em; } + form.comment textarea { + border-radius: 10px 10px 0 0; + border-bottom: none; + margin: 0; } + form.comment button { + border-radius: 0 0 10px 10px; margin: 0; } html { @@ -192,7 +217,7 @@ main { footer { background-color: #6bb8c4; - font-size: 12pt; + font-size: 0.7em; text-align: center; padding: 10px; } @@ -207,16 +232,24 @@ h1 { font-size: 1.5em; font-weight: bold; } +h2 { + font-size: 1.25em; + font-weight: bold; } + +h3 { + font-size: 1em; + font-weight: bold; } + a { - text-decoration: underline; - color: #2b153f; + text-decoration: underline #c9dbe0; + color: #1e464c; border-radius: 3px; } a:hover { - color: #180c23; } + text-decoration-color: #1e464c; } :focus { outline: none; - box-shadow: 0 0 1.5px 1px #2b153f; } + box-shadow: 0 0 1.5px 1px #1e464c; } ::-moz-focus-inner { border: none; } @@ -240,12 +273,12 @@ button, .btn_row a { text-decoration: none; text-align: center; font-size: 100%; + color: #250f2d; border-radius: 10px; padding: 10px; border: 1px solid #51808c; background-color: #c9dbe0; - color: #250f2d; - margin: 10px 5px; } + margin: 10px 0; } button:hover, .btn_row a:hover { background-color: #a9c6cd; } button:focus, .btn_row a:focus { @@ -265,30 +298,26 @@ button, .btn_row a { .error { border-radius: 10px; padding: 10px; - border: 1px solid #ff6798; - background-color: #ffcddd; - color: #250f2d; } + border: 1px solid #ff79a3; + background-color: #ffdfe9; } .info { border-radius: 10px; padding: 10px; - border: 1px solid #6562ff; - background-color: #c9c8ff; - color: #250f2d; } + border: 1px solid #7d79ff; + background-color: #e0dfff; } .warning { border-radius: 10px; padding: 10px; - border: 1px solid #f6b500; - background-color: #ffd45d; - color: #250f2d; } + border: 1px solid #ffd255; + background-color: #ffedbb; } .success { border-radius: 10px; padding: 10px; - border: 1px solid #00d74c; - background-color: #a4ffc4; - color: #250f2d; } + border: 1px solid #84ff72; + background-color: #ddffd8; } .tooltip { position: relative; @@ -408,27 +437,46 @@ iframe { margin: 1ex; } ul { - padding: 0 20px; + padding: 0; list-style-type: none; } - ul li > a { - display: block; - text-decoration: none; - padding: 15px; - margin: 10px 5px; - border-radius: 10px; - border: 1px solid transparent; } - ul li > a:hover { - border-color: #51808c; - background-color: white; } - ul li > a:focus { - border-color: #51808c; - background-color: white; - box-shadow: 0 0 1.5px 1px #6bb8c4; } - ul li > a .details { - font-size: 0.7em; - display: flex; - flex-wrap: wrap; - margin: 5px; - gap: 5px 20px; } - ul li > a .details p { - margin: 0; } + +li > a { + display: block; + padding: 15px; + margin: 10px 5px; + border-radius: 10px; + border: 1px solid transparent; + text-decoration: none; } + li > a .title { + text-decoration: underline #c9dbe0; } + li > a .details { + font-size: 0.7em; + display: flex; + flex-wrap: wrap; + margin: 5px; + gap: 5px 20px; } + li > a .details p { + margin: 0; } + li > a:hover { + border-color: #51808c; + background-color: white; } + li > a:hover .title { + text-decoration-color: currentColor; } + li > a:focus { + border-color: #51808c; + background-color: white; + box-shadow: 0 0 1.5px 1px #6bb8c4; } + +li.comment { + border-radius: 10px; + padding: 10px; + border: 1px solid rgba(107, 184, 196, 0.75); + background-color: white; + margin: 1em 0; + font-size: 0.7em; } + li.comment .author { + font-weight: bold; } + li.comment .date { + font-size: 0.7em; } + li.comment p { + margin: 0.5em; } diff --git a/mainsite/static/js/gestiojeux.js b/mainsite/static/js/gestiojeux.js new file mode 100644 index 0000000..9fdf679 --- /dev/null +++ b/mainsite/static/js/gestiojeux.js @@ -0,0 +1,25 @@ +const MOBILE_NAV_PAGE_SIZE = 475; // px +const MOBILE_NAV_TOGGLE_TIME = 300; // msec +const TEXTAREA_MIN_SIZE = 120; // px + +function mobile_nav_toggle() { + $("nav > a").slideToggle(MOBILE_NAV_TOGGLE_TIME); +} + +$(window).resize(function () { + if(window.innerWidth > MOBILE_NAV_PAGE_SIZE) { + $("nav > a").show(0); + } + else { + $("nav > a").hide(0); + } +}); + +$('textarea').each(function () { + this.style.height = Math.max(this.scrollHeight, TEXTAREA_MIN_SIZE) + 'px'; + this.style.resize = 'none'; + this.style.overflowY = 'hidden'; +}).on('input', function () { + this.style.height = 'auto'; + this.style.height = Math.max(this.scrollHeight, TEXTAREA_MIN_SIZE) + 'px'; +}); diff --git a/mainsite/templates/base.html b/mainsite/templates/base.html index 88d3ef1..70570d6 100644 --- a/mainsite/templates/base.html +++ b/mainsite/templates/base.html @@ -1,3 +1,5 @@ +{% load static %} + @@ -17,7 +19,7 @@ {% include "partials/footer.html" %} - {% include "partials/base_js.html" %} + {% block "extra_foot" %}{% endblock %} diff --git a/mainsite/templates/partials/base_js.html b/mainsite/templates/partials/base_js.html deleted file mode 100644 index 573149b..0000000 --- a/mainsite/templates/partials/base_js.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/mainsite/templates/partials/head.html b/mainsite/templates/partials/head.html index 6f29c80..550bf1e 100644 --- a/mainsite/templates/partials/head.html +++ b/mainsite/templates/partials/head.html @@ -4,5 +4,5 @@ GestioJeux - + diff --git a/mainsite/templates/partials/header.html b/mainsite/templates/partials/header.html index f251a0e..842b564 100644 --- a/mainsite/templates/partials/header.html +++ b/mainsite/templates/partials/header.html @@ -13,8 +13,8 @@ {% if request.user.is_authenticated %}
    {{ request.user.username }}
    - {% else %} + {% else %} + Connexion {% endif %} - {# #} {% endwith %}