From 1011ec8dde30d60fe554a90a7dd83eef5829521f Mon Sep 17 00:00:00 2001
From: Ondrej Rehounek <ondra.rehounek@seznam.cz>
Date: Thu, 11 Nov 2021 20:33:07 +0100
Subject: [PATCH] district: Calendar via mixin, program page to menu, program
 from redmine via fetch

---
 district/blocks.py                            |  33 +-----
 .../migrations/0005_auto_20211108_2126.py     |  41 ++-----
 .../migrations/0006_auto_20211111_1130.py     |  36 ++++++
 district/models.py                            |  21 +++-
 district/templates/district/base.html         |  90 +++++++-------
 .../district/blocks/program_block.html        | 110 +++++++-----------
 .../district/district_contact_page.html       |   6 +-
 .../district/district_program_page.html       |   8 --
 region/blocks.py                              |   2 +-
 .../0002_regionhomepage_subheader.py          |  52 +++++++++
 region/models.py                              |   7 ++
 region/templates/region/base.html             |  11 +-
 .../region/blocks/homepage_header_block.html  |  28 +++++
 .../templates/region/region_contact_page.html |   4 +-
 .../calendar_current_events_snippet.html      |  42 +++++++
 15 files changed, 278 insertions(+), 213 deletions(-)
 create mode 100644 district/migrations/0006_auto_20211111_1130.py
 create mode 100644 region/migrations/0002_regionhomepage_subheader.py
 create mode 100644 shared/templates/shared/calendar_current_events_snippet.html

diff --git a/district/blocks.py b/district/blocks.py
index 1d960c44..56cda397 100644
--- a/district/blocks.py
+++ b/district/blocks.py
@@ -1,17 +1,12 @@
-from django.forms import Select
 from wagtail.core.blocks import (
     CharBlock,
-    ChooserBlock,
     IntegerBlock,
-    ListBlock,
+    PageChooserBlock,
     StructBlock,
     TextBlock,
-    URLBlock,
 )
 from wagtail.images.blocks import ImageChooserBlock
 
-from shared.models import Person
-
 
 class HomepageHeaderBlock(StructBlock):
     title = CharBlock(label="Titulek", required=True)
@@ -24,33 +19,11 @@ class HomepageHeaderBlock(StructBlock):
         label = "Nadpis s obrázkem"
 
 
-class PersonChooserBlock(ChooserBlock):
-    target_model = Person
-    widget = Select
-
-    # TODO check if this is needed
-    def value_for_form(self, value):
-        if isinstance(value, self.target_model):
-            return value.pk
-        else:
-            return value
-
-
-class ProgramItemBlock(StructBlock):
-    title = CharBlock(label="Název", required=True)
-    issue_link = URLBlock(label="Odkaz na redmine", required=True)
-    completion_percentage = IntegerBlock(label="Procento dokončení", required=True)
-
-
 class ProgramBlock(StructBlock):
     headline = CharBlock(label="Titulek bloku", required=True)
     perex = TextBlock(label="Krátký text pod nadpisem", required=True)
-    person = PersonChooserBlock(
-        label="Osoba", required=True
-    )  # TODO Page chooser block should suffice
-    completion_percentage = IntegerBlock(label="Procento dokončení", required=True)
-    program_items = ListBlock(ProgramItemBlock())
-    # program_items = TableBlock(label="Tabulka plnění programu", required=True)
+    person = PageChooserBlock(label="Garant", page_type=["district.DistrictPersonPage"])
+    redmine_issue = IntegerBlock(label="Číslo Redmine issue", required=True)
 
     class Meta:
         template = "district/blocks/program_block.html"
diff --git a/district/migrations/0005_auto_20211108_2126.py b/district/migrations/0005_auto_20211108_2126.py
index 1cdb8e07..f4f4cd37 100644
--- a/district/migrations/0005_auto_20211108_2126.py
+++ b/district/migrations/0005_auto_20211108_2126.py
@@ -187,47 +187,20 @@ class Migration(migrations.Migration):
                                         ),
                                         (
                                             "person",
-                                            district.blocks.PersonChooserBlock(
-                                                label="Osoba", required=True
+                                            wagtail.core.blocks.PageChooserBlock(
+                                                label="Garant",
+                                                page_type=[
+                                                    "district.DistrictPersonPage"
+                                                ],
                                             ),
                                         ),
                                         (
-                                            "completion_percentage",
+                                            "redmine_issue",
                                             wagtail.core.blocks.IntegerBlock(
-                                                label="Procento dokončení",
+                                                label="Číslo Redmine issue",
                                                 required=True,
                                             ),
                                         ),
-                                        (
-                                            "program_items",
-                                            wagtail.core.blocks.ListBlock(
-                                                wagtail.core.blocks.StructBlock(
-                                                    [
-                                                        (
-                                                            "title",
-                                                            wagtail.core.blocks.CharBlock(
-                                                                label="Název",
-                                                                required=True,
-                                                            ),
-                                                        ),
-                                                        (
-                                                            "issue_link",
-                                                            wagtail.core.blocks.URLBlock(
-                                                                label="Odkaz na redmine",
-                                                                required=True,
-                                                            ),
-                                                        ),
-                                                        (
-                                                            "completion_percentage",
-                                                            wagtail.core.blocks.IntegerBlock(
-                                                                label="Procento dokončení",
-                                                                required=True,
-                                                            ),
-                                                        ),
-                                                    ]
-                                                )
-                                            ),
-                                        ),
                                     ]
                                 ),
                             )
diff --git a/district/migrations/0006_auto_20211111_1130.py b/district/migrations/0006_auto_20211111_1130.py
new file mode 100644
index 00000000..631b32ae
--- /dev/null
+++ b/district/migrations/0006_auto_20211111_1130.py
@@ -0,0 +1,36 @@
+# Generated by Django 3.2.8 on 2021-11-11 10:30
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("calendar_utils", "0002_auto_20200523_0243"),
+        ("district", "0005_auto_20211108_2126"),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name="districthomepage",
+            name="calendar_embed_link",
+        ),
+        migrations.AddField(
+            model_name="districthomepage",
+            name="calendar",
+            field=models.ForeignKey(
+                blank=True,
+                null=True,
+                on_delete=django.db.models.deletion.PROTECT,
+                to="calendar_utils.calendar",
+            ),
+        ),
+        migrations.AddField(
+            model_name="districthomepage",
+            name="calendar_url",
+            field=models.URLField(
+                blank=True, null=True, verbose_name="URL kalendáře ve formátu iCal"
+            ),
+        ),
+    ]
diff --git a/district/models.py b/district/models.py
index e5d49e4b..3d24475d 100644
--- a/district/models.py
+++ b/district/models.py
@@ -17,13 +17,14 @@ from wagtail.core.fields import RichTextField, StreamField
 from wagtail.core.models import Page
 from wagtailmetadata.models import MetadataPageMixin
 
+from calendar_utils.models import CalendarMixin
 from shared.models import ArticleMixin, Person, SubpageMixin
 from uniweb.constants import RICH_TEXT_FEATURES
 
 from .blocks import HomepageHeaderBlock, ProgramBlock
 
 
-class DistrictHomePage(MetadataPageMixin, Page):
+class DistrictHomePage(MetadataPageMixin, CalendarMixin, Page):
     ### FIELDS
 
     subheader = StreamField(
@@ -39,10 +40,10 @@ class DistrictHomePage(MetadataPageMixin, Page):
     calendar_button_text = models.CharField(
         "Text tlačítka kalendáře", max_length=256, default="Kalendář"
     )
-    calendar_embed_link = models.URLField(
-        "Odkaz na embed kalendář",
-        help_text="Mělo by začínat 'https://calendar.google.com/calendar/embed?...'",
-    )
+    # calendar_embed_link = models.URLField(
+    #     "Odkaz na embed kalendář",
+    #     help_text="Mělo by začínat 'https://calendar.google.com/calendar/embed?...'",
+    # )  # TODO NOT EMBED
 
     facebook = models.URLField("Facebook URL", blank=True, null=True)
     twitter = models.URLField("Twitter URL", blank=True, null=True)
@@ -95,7 +96,6 @@ class DistrictHomePage(MetadataPageMixin, Page):
         FieldPanel("articles_title"),
         FieldPanel("region_map_button_text"),
         FieldPanel("calendar_button_text"),
-        FieldPanel("calendar_embed_link"),
     ]
 
     promote_panels = [
@@ -130,6 +130,7 @@ class DistrictHomePage(MetadataPageMixin, Page):
             gettext_lazy("Lidé v zápatí stránky"),
         ),
         CommentPanel(),
+        FieldPanel("calendar_url"),
     ]
 
     ### RELATIONS
@@ -162,6 +163,10 @@ class DistrictHomePage(MetadataPageMixin, Page):
     def people_page(self):
         return self._first_subpage_of_type(DistrictPeoplePage)
 
+    @property
+    def program_page(self):
+        return self._first_subpage_of_type(DistrictProgramPage)
+
     @property
     def contact_page(self):
         return self._first_subpage_of_type(DistrictContactPage)
@@ -174,6 +179,10 @@ class DistrictHomePage(MetadataPageMixin, Page):
     def root_page(self):
         return self
 
+    @property
+    def has_calendar(self):
+        return self.calendar_id is not None
+
 
 class DistrictArticleTag(TaggedItemBase):
     content_object = ParentalKey(
diff --git a/district/templates/district/base.html b/district/templates/district/base.html
index 4653aa6d..a099b49c 100644
--- a/district/templates/district/base.html
+++ b/district/templates/district/base.html
@@ -78,14 +78,20 @@
           </div>
 
           <div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
-              <ul class="navbar-menu text-white">
-                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.articles_page %}" class="navbar-menu__link">{{ page.root_page.articles_page }}</a></li>
-                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.people_page %}" class="navbar-menu__link">{{ page.root_page.people_page }}</a></li>
-                  {% comment %}
-                  <li class="navbar-menu__item"><a href="/komunalni-program/" class="navbar-menu__link">Komunální program</a></li>
-                  {% endcomment %}
-                  <li class="navbar-menu__item"><a href="{% pageurl page.root_page.contact_page %}" class="navbar-menu__link">{{ page.root_page.contact_page }}</a></li>
-              </ul>
+            <ul class="navbar-menu text-white">
+              {% if page.root_page.articles_page %}
+                <li class="navbar-menu__item"><a href="{% pageurl page.root_page.articles_page %}" class="navbar-menu__link">{{ page.root_page.articles_page }}</a></li>
+              {% endif %}
+              {% if page.root_page.people_page %}
+                <li class="navbar-menu__item"><a href="{% pageurl page.root_page.people_page %}" class="navbar-menu__link">{{ page.root_page.people_page }}</a></li>
+              {% endif %}
+              {% if page.root_page.program_page %}
+                <li class="navbar-menu__item"><a href="{% pageurl page.root_page.program_page %}" class="navbar-menu__link">{{ page.root_page.program_page }}</a></li>
+              {% endif %}
+              {% if page.root_page.contact_page %}
+                <li class="navbar-menu__item"><a href="{% pageurl page.root_page.contact_page %}" class="navbar-menu__link">{{ page.root_page.contact_page }}</a></li>
+              {% endif %}
+            </ul>
           </div>
 
           <div v-if="show || isLgScreenSize" class="navbar__actions navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto self-start flex flex-col sm:flex-row lg:flex-col sm:space-x-4 space-y-2 sm:space-y-0 lg:space-y-2 xl:flex-row xl:space-x-2 xl:space-y-0">
@@ -158,32 +164,20 @@
 
       <aside class="subnav-aside">
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('regions')}">
-{#          <a @click="toggleView('regions')" class="subnav-aside__close"><i class="ico--close"></i></a>#}
           <ui-region-map class="container container--default" />
         </div>
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('calendar')}">
-{#          <a @click="toggleView('calendar')" class="subnav-aside__close"><i class="ico--close"></i></a>#}
-          <div class="container container--default">
-              <iframe src="{{ page.root_page.calendar_embed_link }}" style="border-width:0; width: 100%; height: 410px; border: 0; overflow: hidden;"></iframe>
-              <p class="mt-4">
-                <a class="btn btn--orange-200 btn--hoveractive" href="{{ page.root_page.calendar_embed_link }}">
-                  <span class="btn__body">Zobrazit všechny akce</span>
-                </a>
-              </p>
-
-          </div>
+          {% include "shared/calendar_current_events_snippet.html" %}
         </div>
       </aside>
     </ui-view-provider>
-
-
   </ui-app>
 </div>
 
 
   {% block subheader %}{% endblock %}
   <div class="container container--default lg:py-4">
-  {% block content %}{% endblock %}
+    {% block content %}{% endblock %}
   </div>
 
 
@@ -203,34 +197,34 @@
         </section>
 
         <section class="footer__main-links bg-grey-700 text-white lg:grid grid-cols-3 gap-4">
-            <div class="pb-4">
-              <ui-footer-collapsible label="Připoj se">
-                <ul class="mt-6 space-y-2 text-grey-200">
-                    <li><a href="{{ page.root_page.contact_newcomers|default:"https://nalodeni.pirati.cz" }}">Zájemci o členství</a></li>
-                    <li><a href="{{ page.root_page.contact_page.url }}">Dej nám vědět</a></li>
-                    <li><a href="https://nalodeni.pirati.cz">Nalodění</a></li>
-                </ul>
-              </ui-footer-collapsible>
-            </div>
+          <div class="pb-4">
+            <ui-footer-collapsible label="Připoj se">
+              <ul class="mt-6 space-y-2 text-grey-200">
+                <li><a href="{{ page.root_page.contact_newcomers|default:"https://nalodeni.pirati.cz" }}">Zájemci o členství</a></li>
+                <li><a href="{{ page.root_page.contact_page.url }}">Dej nám vědět</a></li>
+                <li><a href="https://nalodeni.pirati.cz">Nalodění</a></li>
+              </ul>
+            </ui-footer-collapsible>
+          </div>
 
-            <div class="pb-4 border-t border-grey-400 lg:border-t-0">
-              <ui-footer-collapsible label="Makáme">
-                <ul class="mt-6 space-y-2 text-grey-200">
-                    <li><a href="{{ page.root_page.people_page.url }}">{{ page.root_page.people_page }}</a></li>
-                    <li><a href="{{ page.root_page.articles_page.url }}">{{ page.root_page.articles_page }}</a></li>
-                </ul>
-              </ui-footer-collapsible>
-            </div>
+          <div class="pb-4 border-t border-grey-400 lg:border-t-0">
+            <ui-footer-collapsible label="Makáme">
+              <ul class="mt-6 space-y-2 text-grey-200">
+                <li><a href="{{ page.root_page.people_page.url }}">{{ page.root_page.people_page }}</a></li>
+                <li><a href="{{ page.root_page.articles_page.url }}">{{ page.root_page.articles_page }}</a></li>
+              </ul>
+            </ui-footer-collapsible>
+          </div>
 
-            <div class="pb-4 border-t border-grey-400 lg:border-t-0">
-              <ui-footer-collapsible label="Otevřenost">
-                <ul class="mt-6 space-y-2 text-grey-200">
-                    <li><a href="https://ucet.pirati.cz">Transparentní účet</a></li>
-                    <li><a href="https://smlouvy.pirati.cz">Registr smluv</a></li>
-                    <li><a href="https://wiki.pirati.cz/fo/otevrene_ucetnictvi">Otevřené účetnictví</a></li>
-                </ul>
-              </ui-footer-collapsible>
-            </div>
+          <div class="pb-4 border-t border-grey-400 lg:border-t-0">
+            <ui-footer-collapsible label="Otevřenost">
+              <ul class="mt-6 space-y-2 text-grey-200">
+                <li><a href="https://ucet.pirati.cz">Transparentní účet</a></li>
+                <li><a href="https://smlouvy.pirati.cz">Registr smluv</a></li>
+                <li><a href="https://wiki.pirati.cz/fo/otevrene_ucetnictvi">Otevřené účetnictví</a></li>
+              </ul>
+            </ui-footer-collapsible>
+          </div>
         </section>
 
         <section class="footer__social lg:text-right">
diff --git a/district/templates/district/blocks/program_block.html b/district/templates/district/blocks/program_block.html
index c4f9ee1e..a60d2125 100644
--- a/district/templates/district/blocks/program_block.html
+++ b/district/templates/district/blocks/program_block.html
@@ -10,18 +10,20 @@
         </p>
       </div>
     </div>
+    <div id="#app">
+      {{ message }}
+    </div>
     <div class="pt-8 lg:w-1/3 md:pt-0">
       <div class="card">
         <div class="card__body">
           <div class="badge badge--condensed">
-            <a href="/lide/martin-stanek.html" class="avatar badge__avatar avatar--sm">
-              <img src="/assets/bac4c3-0c8ce9ef9b8e4b48c898da14ee6fba5b78836ed019538622f72b4c6584aee7b6.jpg"
-                   alt="Martin Staněk">
+            <a href="{{ self.person.url }}" class="avatar badge__avatar avatar--sm">
+              <img src="{{ self.person.name }}"alt="Martin Staněk">
             </a>
             <div class="badge__body">
               <h2 class="head-heavy-2xs badge__title">
-                <a href="/lide/martin-stanek.html" title="Martin Staněk" class="content-block--nostyle">
-                  Martin Staněk
+                <a href="{{ self.person.url }}" title="Martin Staněk" class="content-block--nostyle">
+                  {{ self.person.name }}
                 </a>
               </h2>
               <p class="badge__occupation">
@@ -31,13 +33,13 @@
               <a href="tel:775 058 555"
                  class="contact-line icon-link content-block--nostyle contact-line--responsive badge__link">
                 <i class="ico--phone"></i>
-                <span>775 058 555</span>
+                <span>{{ self.person.phone }}</span>
               </a>
 
               <a href="mailto:martin.stanek@pirati.cz"
                  class="contact-line icon-link content-block--nostyle contact-line--responsive badge__link">
                 <i class="ico--envelope"></i>
-                <span>martin.stanek@pirati.cz</span>
+                <span>{{ self.person.email }}</span>
               </a>
             </div>
           </div>
@@ -45,9 +47,12 @@
           <div class="content-block">
             <div class="space-y-4 mt-8">
               <div>
-                <a href="https://redmine.pirati.cz/issues/28177" class="contact-line icon-link content-block--nostyle">
+                <a href="https://redmine.pirati.cz/issues/{{ self.redmine_issue }}" class="contact-line icon-link content-block--nostyle">
                   <i class="ico--info"></i>
-                  <span id="redmineid_28177">Plnění programu: 10%</span>
+                  <span>
+                    Plnění programu:
+                    <span data-redmine-issue-id="{{ self.redmine_issue }}">10</span>%
+                  </span>
                 </a>
               </div>
             </div>
@@ -65,74 +70,37 @@
         <td>Stav plnění</td>
       </tr>
       </thead>
-      <tbody>
-      {% for item in self.program_items %}
-        <tr>
-          <td>
-            <a href="{{ item.issue_link }}" target="_blank">
-              {{ item.title }}
-            </a>
-          </td>
-          <td>{{ item.completion_percentage }} %</td>
-        </tr>
-      {% endfor %}
+      <tbody data-redmine-table-id="{{ self.redmine_issue }}">
       </tbody>
     </table>
   </div>
 </article>
 
-<div class="content-block">
-  <div class="space-y-4 mt-8">
-    <div>
-      <a href="https://redmine.pirati.cz/issues/28177" class="contact-line icon-link content-block--nostyle">
-        <i class="ico--info"></i>
-        <span id="redmineid_28177">Plnění programu: 10%</span>
-      </a>
-    </div>
-  </div>
-</div>
-
 <script>
-  fetch('https://redmine.pirati.cz/issues/28177.json')
-  .then(response => response.json())
-  .then(data => console.log(data));
+    function handleOverallData(issue) {
+        document.querySelector('[data-redmine-issue-id="{{ self.redmine_issue }}"]').innerText = issue.done_ratio || 0
+    }
+
+    function handleIssueList(issueList) {
+        const table = document.querySelector('[data-redmine-table-id="{{ self.redmine_issue }}"]')
+        for (const issue of issueList) {
+            table.innerHTML +=
+                `<tr>
+                  <td>
+                    <a href="https://redmine.pirati.cz/issues/${issue.id}" target="_blank">
+                      ${issue.subject || ''}
+                    </a>
+                  </td>
+                  <td>${issue.done_ratio || 0} %</td>
+                </tr>`
+        }
+    }
 
-  fetch('https://redmine.pirati.cz/issues.json?parent_id=28177&sort=id:as')
-  .then(response => response.json())
-  .then(data => console.log(data));
+    fetch('https://redmine.pirati.cz/issues/28177.json')
+        .then(response => response.json())
+        .then(data => handleOverallData(data.issue || {}))
 
-    {#pirates.priorityStack.push(function (context) {#}
-    {#    var url = 'https://redmine.pirati.cz/issues/28177.json';#}
-    {#    var xhr = pirates.createCORSRequest('GET', url);#}
-    {#    if (!xhr) {#}
-    {#        alert('CORS not supported');#}
-    {#        return;#}
-    {#    }#}
-    {#    xhr.onload = function () {#}
-    {#        var doc = JSON.parse(xhr.responseText);#}
-    {#        var redmine = document.getElementById('redmineid_28177');#}
-    {#        redmine.textContent = "Plnění programu: " + doc.issue.done_ratio + "%";#}
-    {#    }#}
-    {#    xhr.onerror = function () {#}
-    {#        console.log('Woops, there was an error making the request.');#}
-    {#    };#}
-    {#    xhr.send();#}
-    {#});#}
-    {#pirates.priorityStack.push(function (context) {#}
-    {#    var url = 'https://redmine.pirati.cz/issues.json?parent_id=28177&sort=id:asc';#}
-    {#    var xhr = pirates.createCORSRequest('GET', url);#}
-    {#    if (!xhr) {#}
-    {#        alert('CORS not supported');#}
-    {#        return;#}
-    {#    }#}
-    {#    xhr.onload = function () {#}
-    {#        var doc = JSON.parse(xhr.responseText);#}
-    {#        var div = document.getElementById('redmine_tasks_28177');#}
-    {#        div.appendChild(pirates.integrations.redmine.tasks(doc));#}
-    {#    }#}
-    {#    xhr.onerror = function () {#}
-    {#        console.log('Woops, there was an error making the request.');#}
-    {#    };#}
-    {#    xhr.send();#}
-    {#});#}
+    fetch('https://redmine.pirati.cz/issues.json?parent_id=28177&sort=id:as')
+        .then(response => response.json())
+        .then(data => handleIssueList(data.issues || []))
 </script>
diff --git a/district/templates/district/district_contact_page.html b/district/templates/district/district_contact_page.html
index b1c6c77b..c913b448 100644
--- a/district/templates/district/district_contact_page.html
+++ b/district/templates/district/district_contact_page.html
@@ -72,9 +72,9 @@
             </div>
 
             <hr class="hr">
-
-            <h2>Sídlo a kontaktní centrum</h2>
-            <strong>Piráti Zlínský kraj</strong>
+{##}
+{#            <h2>Sídlo a kontaktní centrum</h2> FIXME #}
+{#            <strong>Piráti Zlínský kraj</strong>#}
 
           </div>
         </div>
diff --git a/district/templates/district/district_program_page.html b/district/templates/district/district_program_page.html
index 8637887c..3805467f 100644
--- a/district/templates/district/district_program_page.html
+++ b/district/templates/district/district_program_page.html
@@ -6,7 +6,6 @@
   <div class="container container--default py-8">
     <div class="lg:flex lg:mt-8 space-y-16 lg:space-y-0 lg:space-x-8 xl:space-x-16 mb-5">
       <section>
-
         <header>
           <h1 itemprop="headline" class="head-alt-md md:head-alt-lg max-w-5xl mb-8">
             {{ page.title }}
@@ -17,17 +16,10 @@
           {{ page.perex }}
         </p>
 
-{#        {{ page.content }}#}
-
         {% for block in page.content %}
-
           {% include_block block %}
-
         {% endfor %}
-
       </section>
-
     </div>
   </div>
-
 {% endblock %}
diff --git a/region/blocks.py b/region/blocks.py
index ec1d2dfa..89da28d7 100644
--- a/region/blocks.py
+++ b/region/blocks.py
@@ -3,7 +3,7 @@ from wagtail.images.blocks import ImageChooserBlock
 
 
 class HomepageHeaderBlock(StructBlock):
-    title = CharBlock(label="Titulek", required=True)
+    title = CharBlock(label="Titulek", required=False, help_text="Nap")
     image = ImageChooserBlock()
     button_text = CharBlock(label="Titulek", required=False)
     button_link = URLBlock(label="Odkaz tlačítka", required=False)
diff --git a/region/migrations/0002_regionhomepage_subheader.py b/region/migrations/0002_regionhomepage_subheader.py
new file mode 100644
index 00000000..3b37cf32
--- /dev/null
+++ b/region/migrations/0002_regionhomepage_subheader.py
@@ -0,0 +1,52 @@
+# Generated by Django 3.2.8 on 2021-11-11 08:48
+
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("region", "0001_initial"),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name="regionhomepage",
+            name="subheader",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "header",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "title",
+                                    wagtail.core.blocks.CharBlock(
+                                        help_text="Nap", label="Titulek", required=False
+                                    ),
+                                ),
+                                ("image", wagtail.images.blocks.ImageChooserBlock()),
+                                (
+                                    "button_text",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=False
+                                    ),
+                                ),
+                                (
+                                    "button_link",
+                                    wagtail.core.blocks.URLBlock(
+                                        label="Odkaz tlačítka", required=False
+                                    ),
+                                ),
+                            ]
+                        ),
+                    )
+                ],
+                blank=True,
+                verbose_name="Blok pod headerem",
+            ),
+        ),
+    ]
diff --git a/region/models.py b/region/models.py
index dfeda9b4..8d873ace 100644
--- a/region/models.py
+++ b/region/models.py
@@ -20,11 +20,18 @@ from wagtailmetadata.models import MetadataPageMixin
 from shared.models import ArticleMixin, Person, SubpageMixin
 from uniweb.constants import RICH_TEXT_FEATURES
 
+from .blocks import HomepageHeaderBlock
+
 # TODO zatím prakticky shodné s district.models - až bude hotové, tak společné věci přenést do shared
 
 
 class RegionHomePage(MetadataPageMixin, Page):
     ### FIELDS
+    subheader = StreamField(
+        [("header", HomepageHeaderBlock())],
+        verbose_name="Blok pod headerem",
+        blank=True,
+    )
 
     content = StreamField(
         [
diff --git a/region/templates/region/base.html b/region/templates/region/base.html
index 64e6fd8d..011fbdb2 100644
--- a/region/templates/region/base.html
+++ b/region/templates/region/base.html
@@ -151,20 +151,11 @@
 
       <aside class="subnav-aside">
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('regions')}">
-          <a @click="toggleView('regions')" class="subnav-aside__close"><i class="ico--close"></i></a>
           <ui-region-map class="container container--default" />
         </div>
         <div class="subnav-aside__item" :class="{'subnav-aside__item--visible': isCurrentView('calendar')}">
-          <a @click="toggleView('calendar')" class="subnav-aside__close"><i class="ico--close"></i></a>
           <div class="container container--default">
-
-              <iframe src="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague" style="border-width:0; width: 100%; height: 410px; border: 0; overflow: hidden;"></iframe>
-              <p class="mt-4">
-                <a class="btn btn--orange-200 btn--hoveractive" href="https://calendar.google.com/calendar/embed?showTitle=0&showNav=0&showDate=0&showPrint=0&showTabs=0&showCalendars=0&showTz=0&mode=AGENDA&height=500&wkst=2&hl=cs&bgcolor=%23FFFFFF&src=kddvdvu3adcjef2kro4j6mm838%40group.calendar.google.com&color=%232952A3&ctz=Europe%2FPrague">
-                  <span class="btn__body">Zobrazit všechny akce</span>
-                </a>
-              </p>
-
+            {% include "shared/calendar_current_events_snippet.html" %}
           </div>
         </div>
       </aside>
diff --git a/region/templates/region/blocks/homepage_header_block.html b/region/templates/region/blocks/homepage_header_block.html
index e69de29b..6a6dd13c 100644
--- a/region/templates/region/blocks/homepage_header_block.html
+++ b/region/templates/region/blocks/homepage_header_block.html
@@ -0,0 +1,28 @@
+{% load wagtailimages_tags %}
+
+<header class="hero py-8 lg:py-16">
+  <div class="container container--default grid lg:grid-cols-7 lg:grid-rows-3 gap-2 items-center">
+    <div class="lg:col-span-3 lg:row-span-2 order-1">
+      <h1 class="head-alt-md md:head-alt-xl">{% firstof self.title page.title %}</h1>
+    </div>
+
+    <div class="lg:row-span-1 lg:col-span-3 order-3">
+      <div class="mt-4 md:mt-8 space-y-4 ">
+        <a href="{{ self.button_link }}"
+           class="btn btn--icon btn--hoveractive btn--fullwidth md:btn--autowidth text-lg">
+          <div class="btn__body-wrap">
+            <div class="btn__body ">{{ self.button_text }}</div>
+            <div class="btn__icon ">
+              <i class="ico--chevron-right"></i>
+            </div>
+          </div>
+        </a>
+      </div>
+    </div>
+
+    <div class="lg:col-span-4 order-2 row-span-1 lg:row-span-3">
+      {% image self.image width-495 as img %}
+      <img src="{{ img.url }}" alt="" class="object-contain h-32 lg:h-80 lg:m-auto hidden md:block">
+    </div>
+  </div>
+</header>
diff --git a/region/templates/region/region_contact_page.html b/region/templates/region/region_contact_page.html
index eaab2163..66901d66 100644
--- a/region/templates/region/region_contact_page.html
+++ b/region/templates/region/region_contact_page.html
@@ -73,8 +73,8 @@
 
             <hr class="hr">
 
-            <h2>Sídlo a kontaktní centrum</h2>
-            <strong>Piráti Zlínský kraj</strong>
+{#            <h2>Sídlo a kontaktní centrum</h2> FIXME #}
+{#            <strong>Piráti Zlínský kraj</strong>#}
 
           </div>
         </div>
diff --git a/shared/templates/shared/calendar_current_events_snippet.html b/shared/templates/shared/calendar_current_events_snippet.html
new file mode 100644
index 00000000..ad780032
--- /dev/null
+++ b/shared/templates/shared/calendar_current_events_snippet.html
@@ -0,0 +1,42 @@
+<div class="container container--default">
+  {% if page.root_page.has_calendar %}
+    {% for event in page.root_page.calendar.current_events %}
+      <div class="grid grid-cols-12 items-center calendar-table-row calendar-table-row--standalone">
+        <div class="col-span-2 text-blue-200 head-alt-md calendar-table-row__col">
+          <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.description %}
+              <p class="font-light text-sm mt-1">{{ event.description | safe }}</p>
+            {% endif %}
+            {% if event.location %}
+              <p class="font-light text-sm mt-1">{{ event.location }}</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 text-violet-300 mr-1" aria-hidden="true"></i>
+              <span>Mapa</span>
+            </a>
+          {% endif %}
+        </div>
+      </div>
+    {% empty %}
+      <div class="content-block">
+        <p>Žádné události.</p>
+      </div>
+    {% endfor %}
+  {% else %}
+    <div class="content-block">
+      <p>Žádné události.</p>
+    </div>
+  {% endif %}
+</div>
-- 
GitLab