From 8a44cd39d99c35ef63d049080978dda6d3ca4b8b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Thu, 29 Jul 2021 17:09:58 +0200
Subject: [PATCH] elections2021: Calendar page and home page widget
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Jan Hamal Dvořák <mordae@anilinux.org>
---
 .../0035_elections2021calendarpage.py         | 33 ++++++++
 elections2021/models.py                       | 77 +++++++++++++++++++
 .../elections2021_calendar_page.html          | 58 ++++++++++++++
 .../elections2021_home_page.html              | 60 +++++++++++++++
 4 files changed, 228 insertions(+)
 create mode 100644 elections2021/migrations/0035_elections2021calendarpage.py
 create mode 100644 elections2021/templates/elections2021/elections2021_calendar_page.html

diff --git a/elections2021/migrations/0035_elections2021calendarpage.py b/elections2021/migrations/0035_elections2021calendarpage.py
new file mode 100644
index 00000000..9e7140d7
--- /dev/null
+++ b/elections2021/migrations/0035_elections2021calendarpage.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.2.5 on 2021-07-29 13:00
+
+from django.db import migrations, models
+import django.db.models.deletion
+import shared.models
+import wagtailmetadata.models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('wagtailcore', '0062_comment_models_and_pagesubscription'),
+        ('wagtailimages', '0023_add_choose_permissions'),
+        ('calendar_utils', '0002_auto_20200523_0243'),
+        ('elections2021', '0034_auto_20210715_2354'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Elections2021CalendarPage',
+            fields=[
+                ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.page')),
+                ('calendar_url', models.URLField(blank=True, null=True, verbose_name='URL kalendáře ve formátu iCal')),
+                ('calendar', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='calendar_utils.calendar')),
+                ('photo', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='wagtailimages.image', verbose_name='hlavní fotka')),
+                ('search_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailimages.image', verbose_name='Search image')),
+            ],
+            options={
+                'verbose_name': 'Kalendář',
+            },
+            bases=(shared.models.SubpageMixin, wagtailmetadata.models.WagtailImageMetadataMixin, 'wagtailcore.page', models.Model),
+        ),
+    ]
diff --git a/elections2021/models.py b/elections2021/models.py
index 07b43248..1d69e8b9 100644
--- a/elections2021/models.py
+++ b/elections2021/models.py
@@ -34,6 +34,7 @@ from wagtail.images.blocks import ImageChooserBlock
 from wagtail.images.edit_handlers import ImageChooserPanel
 from wagtailmetadata.models import MetadataPageMixin
 
+from calendar_utils.models import CalendarMixin
 from shared.models import ArticleMixin, SubpageMixin
 from shared.utils import get_subpage_url, subscribe_to_newsletter
 from tuning import help
@@ -298,6 +299,7 @@ class Elections2021HomePage(MetadataPageMixin, RoutablePageMixin, Page):
         "elections2021.Elections2021MythsPage",
         "elections2021.Elections2021DownloadsPage",
         "elections2021.Elections2021GovernmentTeamPage",
+        "elections2021.Elections2021CalendarPage",
     ]
 
     ### OTHERS
@@ -359,6 +361,29 @@ class Elections2021HomePage(MetadataPageMixin, RoutablePageMixin, Page):
     def government_team_page_url(self):
         return get_subpage_url(self, Elections2021GovernmentTeamPage)
 
+    @cached_property
+    def has_calendar(self):
+        try:
+            self.calendar
+            return True
+        except (Page.DoesNotExist, AttributeError):
+            return False
+
+    @cached_property
+    def calendar_page_url(self):
+        return get_subpage_url(self, Elections2021CalendarPage)
+
+    @cached_property
+    def calendar(self):
+        return (
+            self.get_descendants()
+            .type(Elections2021CalendarPage)
+            .live()
+            .specific()
+            .first()
+            .calendar
+        )
+
     @cached_property
     def gdpr_and_cookies_url(self):
         if self.gdpr_and_cookies_page:
@@ -2348,3 +2373,55 @@ class Elections2021GovernmentTeamPage(SubpageMixin, MetadataPageMixin, Page):
 
     def get_meta_image(self):
         return self.search_image or self.photo
+
+
+class Elections2021CalendarPage(SubpageMixin, MetadataPageMixin, CalendarMixin, Page):
+    ### FIELDS
+
+    photo = models.ForeignKey(
+        "wagtailimages.Image",
+        on_delete=models.PROTECT,
+        blank=True,
+        null=True,
+        verbose_name="hlavní fotka",
+    )
+
+    ### PANELS
+
+    content_panels = Page.content_panels + [
+        ImageChooserPanel("photo"),
+        FieldPanel("calendar_url"),
+    ]
+
+    promote_panels = [
+        MultiFieldPanel(
+            [
+                FieldPanel("slug"),
+                FieldPanel("seo_title"),
+                FieldPanel("search_description"),
+                ImageChooserPanel("search_image"),
+                HelpPanel(help.build(help.NO_SEO_TITLE, NO_SEARCH_IMAGE_USE_PHOTO)),
+            ],
+            gettext_lazy("Common page configuration"),
+        ),
+        CommentPanel(),
+    ]
+
+    settings_panels = []
+
+    ### RELATIONS
+
+    parent_page_types = ["elections2021.Elections2021HomePage"]
+    subpage_types = []
+
+    ### OTHERS
+
+    class Meta:
+        verbose_name = "Kalendář"
+
+    def get_meta_image(self):
+        return self.search_image or self.photo
+
+    @property
+    def has_calendar(self):
+        return self.calendar_id is not None
diff --git a/elections2021/templates/elections2021/elections2021_calendar_page.html b/elections2021/templates/elections2021/elections2021_calendar_page.html
new file mode 100644
index 00000000..920169fd
--- /dev/null
+++ b/elections2021/templates/elections2021/elections2021_calendar_page.html
@@ -0,0 +1,58 @@
+{% extends "elections2021/base.html" %}
+{% load static wagtailcore_tags %}
+
+{% block content_header %}
+  <article class=" relative bg-lemon md:bg-split-color px-4 md:pl-8 md:pr-0 2xl:px-8 hero py-0 w-full ">
+    <div class="2xl:container w-auto bg-lemon md:pl-20 pr-0 grid lg:grid-rows-1 h-40 sm:h-56 md:h-64  lg:grid-cols-7 items-center 2xl:mx-auto">
+      <div class="lg:row-span-1 lg:col-span-4 order-1 md:pr-20">
+        <h1 class="head-alt-md sm:head-alt-lg pt-1 max-w-xl">{{ page.title }}</h1>
+        <h2 class="head-alt-sm sm:head-alt-md pt-1 max-w-xl">Kde nás můžete potkat?</h2>
+      </div>
+      <div class="text-center hidden lg:block lg:row-span-2 lg:col-span-3 order-2 h-full 2xl:right-0 2xl:text-right">
+        <i class="h-64 py-12 inline-block ico--calendar banner__icon"></i>
+      </div>
+    </div>
+  </article>
+{% endblock %}
+
+{% block content %}
+<div class="container container--default pt-8 pb-16 lg:py-24">
+
+  {% for event in page.calendar.future_events %}
+  <div class="grid grid-cols-12 items-center calendar-table-row my-1">
+    <div class="col-span-2 head-alt-md calendar-table-row__col" style="color: #92ac00">
+      <span>{{ event.begin|date:"j." }}</span>
+    </div>
+    <div class="col-span-8 grid grid-cols-3 calendar-table-row__col">
+      <div class="col-span-3 md:col-span-1">
+        <strong class="block">{{ event.begin|date:"l j. E"|capfirst }}</strong>
+        <p class="font-light text-sm mt-1">{{ event.duration }}</p>
+      </div>
+      <div class="col-span-3 md:col-span-2 mt-4 md:mt-0">
+        <strong class="block">{{ event.name }}</strong>
+        {% if event.location %}
+        <p class="font-light text-sm mt-1">{{ event.location }}</p>
+        {% endif %}
+
+        {% if event.description %}
+        <p class="font-light text-sm mt-1">{{ event.description }}</p>
+        {% endif %}
+      </div>
+    </div>
+    <div class="col-span-2 text-center font-light calendar-table-row__col">
+      {% if event.location %}
+      <a href="https://maps.google.com/maps?q={{ event.location }}" class="icon-link">
+        <i class="ico--location" style="color: #92ac00" aria-hidden="true"></i>
+        <span>Mapa</span>
+      </a>
+      {% endif %}
+    </div>
+  </div>
+  {% empty %}
+  <div class="calendar__row__content">
+    <p>Žádné události.</p>
+  </div>
+  {% endfor %}
+
+</div>
+{% endblock %}
diff --git a/elections2021/templates/elections2021/elections2021_home_page.html b/elections2021/templates/elections2021/elections2021_home_page.html
index 07e89815..9e5a6812 100644
--- a/elections2021/templates/elections2021/elections2021_home_page.html
+++ b/elections2021/templates/elections2021/elections2021_home_page.html
@@ -69,6 +69,66 @@
     </div>
   </section>
 
+  {% if page.has_calendar %}
+  <section class="mt-16 md:mb-16 lg:my-28 container-padding--zero lg:container-padding--auto">
+    <div class="lead-collector inline-flex w-full">
+      <div class="lead-collector-icon bg-acidgreen max-w-max p-10 hidden md:flex" style="height: max-content">
+        <i class="ico--calendar text-black" style="font-size: 51px"></i>
+      </div>
+      <div class="lead-collector-body bg-black py-10 px-8 w-full">
+        <h1 class="head-alt-lg text-white mb-4">Kalendář akcí</h1>
+        <div class="bg-black">
+          {% for event in page.calendar.current_events %}
+          <div class="grid grid-cols-12 items-center my-1">
+            <div class="col-span-2 head-alt-md calendar-table-row__col text-acidgreen border-acidgreen">
+              <span>{{ event.begin|date:"j." }}</span>
+            </div>
+            <div class="col-span-8 grid grid-cols-3 calendar-table-row__col text-white border-black">
+              <div class="col-span-3 md:col-span-1">
+                <strong class="block">{{ event.begin|date:"l j. E"|capfirst }}</strong>
+                <p class="font-light text-sm mt-1">{{ event.duration }}</p>
+              </div>
+              <div class="col-span-3 md:col-span-2 mt-4 md:mt-0">
+                <strong class="block">{{ event.name }}</strong>
+                {% if event.location %}
+                <p class="font-light text-sm mt-1">{{ event.location }}</p>
+                {% endif %}
+
+                {% if event.description %}
+                <p class="font-light text-sm mt-1">{{ event.description }}</p>
+                {% endif %}
+              </div>
+            </div>
+            <div class="col-span-2 text-center font-light calendar-table-row__col text-white border-black">
+              {% if event.location %}
+              <a href="https://maps.google.com/maps?q={{ event.location }}" class="icon-link">
+                <i class="ico--location" style="color: #92ac00" aria-hidden="true"></i>
+                <span>Mapa</span>
+              </a>
+              {% endif %}
+            </div>
+          </div>
+          {% empty %}
+          <div class="calendar__row__content">
+            <p>Žádné události.</p>
+          </div>
+          {% endfor %}
+        </div>
+        <div>
+          <a href="{{ page.root_page.calendar_page_url }}" class="btn btn--icon bg-white text-black btn--hoveractive border mr-6 mt-5 bg-white">
+            <div class="btn__body-wrap">
+              <div class="btn__body bg-white text-black py-5 px-12 hover:text-white hover:bg-black hover:border-black">Chci vás potkat jindy</div>
+              <div class="btn__icon px-5 bg-white text-black">
+                <i class="ico--chevron-right"></i>
+              </div>
+            </div>
+          </a>
+        </div>
+      </div>
+    </div>
+  </section>
+  {% endif %}
+
   {% if page.elections_date %}
     <section class="my-16 lg:my-28 container-padding--zero lg:container-padding--auto">
       <aside class="bg-black text-white px-4 py-12 lg:py-16 lg:px-24 ">
-- 
GitLab