diff --git a/src/agenda_culturel/settings/base.py b/src/agenda_culturel/settings/base.py index 100c022..c18f281 100644 --- a/src/agenda_culturel/settings/base.py +++ b/src/agenda_culturel/settings/base.py @@ -40,6 +40,7 @@ INSTALLED_APPS = [ "colorfield", 'django_extensions', 'django_better_admin_arrayfield', + 'django_filters', ] MIDDLEWARE = [ @@ -124,6 +125,10 @@ LANGUAGES = ( ) +# Auth + +LOGIN_REDIRECT_URL = "/" + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ diff --git a/src/agenda_culturel/static/css/style.css b/src/agenda_culturel/static/css/style.css index fdc30d7..c440ffd 100644 --- a/src/agenda_culturel/static/css/style.css +++ b/src/agenda_culturel/static/css/style.css @@ -6,6 +6,11 @@ body { padding-bottom: 1em; } +h1 a, h1 a:visited { + text-decoration: none; + color: #000; +} + [role="doc-subtitle"] { font-size: 140%; margin-top: -1em; @@ -16,6 +21,12 @@ body { font-weight: bold; } +.button { + box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.3); +} +.button:hover { + box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.2); +} .cat, .mode { line-height: 2.4em; @@ -34,16 +45,16 @@ span.cat, span.mode { } .mode { - background-color: #CCC; + background-color: rgb(230, 235, 235); } a.mode:hover { - background-color: #666; + background-color: rgb(133, 136, 136); color: #FFF; } .mode.selected { - background-color: #444; + background-color: rgb(65, 67, 67); color: #fff; } @@ -71,7 +82,7 @@ a.mode:hover { font-size: 80%; display: inline-block; padding: 0.1em 0.8em; - border-radius: .4em; + border-radius: .8em; } .warning-simple { @@ -79,7 +90,53 @@ a.mode:hover { } .warning { - background: #EEE; + background-color: rgb(230, 235, 235); padding: 1em; border-radius: 1.5em; -} \ No newline at end of file +} + +.rich_button { + text-decoration: none; + display: inline-block; + background-color: rgb(230, 235, 235); + color: #000; + text-align: center; + border-radius: 1em; + line-height: 2em; + overflow: hidden; +} + + +.rich_button span { + display: inline-block; + height: 2em; + width: 2em; + font-weight: bold; + background-color: #008080; + color: #fff; + border-radius: 1em; + margin-left: 0.2em; + box-shadow: 0 0 0.2em rgba(0, 0, 0, 0.3); +} + +.rich_button:hover { + background: rgb(133, 136, 136); + color: #fff; +} + +.rich_button:hover span { + background-color: rgb(1, 140, 140); +} + +#add_content_header, #edit_content_header { + font-size: 120%; + position: fixed; + top: 4em; + padding-left: 0.8em; + right: 2em; +} + +#edit_content_header { + top: 1.5em; +} + diff --git a/src/agenda_culturel/templates/agenda_culturel/event.html b/src/agenda_culturel/templates/agenda_culturel/event.html index 9f955db..452d04d 100644 --- a/src/agenda_culturel/templates/agenda_culturel/event.html +++ b/src/agenda_culturel/templates/agenda_culturel/event.html @@ -1,4 +1,4 @@ -{% extends "agenda_culturel/page_events.html" %} +{% extends "agenda_culturel/page-events.html" %} {% block title %}{{ object.title }}{% endblock %} diff --git a/src/agenda_culturel/templates/agenda_culturel/list.html b/src/agenda_culturel/templates/agenda_culturel/list.html index 2934e51..e08b163 100644 --- a/src/agenda_culturel/templates/agenda_culturel/list.html +++ b/src/agenda_culturel/templates/agenda_culturel/list.html @@ -1,14 +1,38 @@ {% extends "agenda_culturel/page.html" %} -{% block title %}Accueil{% endblock %} +{% block title %}Tous les événements{% endblock %} {% block content %} -

Événements

- + + + {% endblock %} \ No newline at end of file diff --git a/src/agenda_culturel/templates/agenda_culturel/page-events.html b/src/agenda_culturel/templates/agenda_culturel/page-events.html index 2befe26..b49aa49 100644 --- a/src/agenda_culturel/templates/agenda_culturel/page-events.html +++ b/src/agenda_culturel/templates/agenda_culturel/page-events.html @@ -19,9 +19,9 @@ {{ mode }} {% else %} {% if category %} - {{ mode }} + {{ mode }} {% else %} - {{ mode }} + {{ mode }} {% endif %} {% endif %} {% endfor %} @@ -29,9 +29,9 @@ @@ -48,9 +48,9 @@ {% if events %} {% for date in dates %} -

{{ date |date:"DATE_FORMAT" }}

{% with events_date=events|in_date:date %} {% if events_date %} +

{{ date |date:"l j F"| capfirst }}

{% for event in events_date %}
  • {% if category %} @@ -58,12 +58,10 @@ {% else %} {% url 'view_mode_cat' selected_mode.name event.category.pk as url_cat %} {{ event.category | small_cat:url_cat }} - {% endif %} {{ event.title }} + {% endif %} {{ event.title }}
  • {% endfor %}
    - {% else %} -

    Aucun événement ce jour-là.

    {% endif %} {% endwith %} {% endfor %} diff --git a/src/agenda_culturel/templates/agenda_culturel/page.html b/src/agenda_culturel/templates/agenda_culturel/page.html index aea17b8..0899de8 100644 --- a/src/agenda_culturel/templates/agenda_culturel/page.html +++ b/src/agenda_culturel/templates/agenda_culturel/page.html @@ -18,17 +18,35 @@ {% block entete_header %} {% endblock %} +{% load event_extra %}
    -

    Les nuits énigmagmatiques

    +

    Les nuits énigmagmatiques

    Agenda culturel de Clermont-Ferrand et des environs
    +
    + {% if user.is_authenticated %} + gérer les événements {% nb_draft_events %} + {% endif %} + {% block add_content %} + ajouter un événement + + {% endblock %} +
    {% block content %}{% endblock %}
    diff --git a/src/agenda_culturel/templates/registration/login.html b/src/agenda_culturel/templates/registration/login.html new file mode 100644 index 0000000..d8771ab --- /dev/null +++ b/src/agenda_culturel/templates/registration/login.html @@ -0,0 +1,40 @@ +{% extends "agenda_culturel/page.html" %} + +{% block title %}Connexion{% endblock %} + +{% block content %} +

    Connexion

    + +{% if form.errors %} +

    Vos identifiants sont incorrects. Veuillez réessayer.

    +{% endif %} + +{% if next %} +{% if user.is_authenticated %} +

    Vous n'avez pas l'autorisation d'accéder à cette page. + Pour y accéder, veuillez vous connecter avec un compte autorisé.

    +{% else %} +

    Veuillez vous identifier pour consulter cette page.

    +{% endif %} +{% else %} +

    Veuillez vous identifier pour consulter cette page.

    +{% endif %} + +
    +{% csrf_token %} + + + + + + + + + +
    {{ form.username.label_tag }}{{ form.username }}
    {{ form.password.label_tag }}{{ form.password }}
    + + +
    + + +{% endblock %} \ No newline at end of file diff --git a/src/agenda_culturel/templatetags/cat_extra.py b/src/agenda_culturel/templatetags/cat_extra.py index 4c3080e..7586e5a 100644 --- a/src/agenda_culturel/templatetags/cat_extra.py +++ b/src/agenda_culturel/templatetags/cat_extra.py @@ -86,6 +86,6 @@ def css_categories(): @register.filter def small_cat(category, url=None): if url is None: - return mark_safe('' + category.name + "") + return mark_safe('' + category.name + "") else: - return mark_safe('' + category.name + "") \ No newline at end of file + return mark_safe('' + category.name + "") \ No newline at end of file diff --git a/src/agenda_culturel/templatetags/event_extra.py b/src/agenda_culturel/templatetags/event_extra.py index d0dce34..9db75bf 100644 --- a/src/agenda_culturel/templatetags/event_extra.py +++ b/src/agenda_culturel/templatetags/event_extra.py @@ -9,3 +9,7 @@ register = template.Library() @register.filter def in_date(event, date): return event.filter((Q(start_day__lte=date) & Q(end_day__gte=date)) | (Q(end_day=None) & Q(start_day=date))) + +@register.simple_tag +def nb_draft_events(): + return Event.objects.filter(status=Event.STATUS.DRAFT).count() diff --git a/src/agenda_culturel/urls.py b/src/agenda_culturel/urls.py index a46f94d..b5de02a 100644 --- a/src/agenda_culturel/urls.py +++ b/src/agenda_culturel/urls.py @@ -3,7 +3,7 @@ from django.conf.urls.static import static from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.urls import path, include, re_path - +from django.contrib.auth import views as auth_views from .views import * @@ -13,11 +13,13 @@ urlpatterns = [ path("", home, name="home"), re_path(r'^(?P' + modes + ')/$', view_mode, name='view_mode'), re_path(r'^(?P' + modes + ')/(?P\d+)/$', view_mode_cat, name='view_mode_cat'), + path("events/", event_list, name='view_all_events'), path("event/-", EventDetailView.as_view(), name="view_event"), path("proposer", EventSubmissionFormView.as_view(), name="event_submission_form"), + path("a-propos", , name="about"), path("admin/", admin.site.urls), + path('accounts/', include('django.contrib.auth.urls')), path("test_app/", include("test_app.urls")), - ] if settings.DEBUG: diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index 45654e9..2ce7b02 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -12,6 +12,11 @@ from django.db.models import Q from django.utils.translation import gettext_lazy as _ from django.utils.translation import activate, get_language_info +import django_filters +from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger +from django.contrib.auth.decorators import login_required + + class DisplayMode(StrEnum): this_week = "this week" @@ -75,7 +80,6 @@ def view_mode_cat(request, mode, cat_id): return render(request, 'agenda_culturel/page-events.html', context) - class EventDetailView(DetailView): model = Event template_name = "agenda_culturel/event.html" @@ -100,3 +104,40 @@ class EventSubmissionFormView(FormView): def create_event(self, valid_data): url = valid_data["url"] create_event_from_submission.delay(url) + + + +class EventFilter(django_filters.FilterSet): + tags = django_filters.CharFilter(lookup_expr='icontains') + + + o = django_filters.OrderingFilter( + # tuple-mapping retains order + fields=( + ('created_date', 'created_date'), + ('modified_date', 'modified_date'), + ('status', 'status'), + ('title', 'title'), + ('start_day', 'start_day'), + ), + ) + + + class Meta: + model = Event + fields = ['title', 'status', 'category', 'tags'] + +@login_required(login_url="/accounts/login/") +def event_list(request): + filter = EventFilter(request.GET, queryset=Event.objects.all()) + paginator = Paginator(filter.qs, 10) + page = request.GET.get('page') + + try: + response = paginator.page(page) + except PageNotAnInteger: + response = paginator.page(1) + except EmptyPage: + response = paginator.page(paginator.num_pages) + + return render(request, 'agenda_culturel/list.html', {'filter': filter, 'paginator_filter': response}) diff --git a/src/requirements.txt b/src/requirements.txt index ed1cc6c..e887aaa 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -28,3 +28,4 @@ cffi==1.16.0 django-extensions==3.2.3 djipsum==1.1.5 django-better-admin-arrayfield==1.4.2 +django-filter==23.3 \ No newline at end of file