diff --git a/elections2021/constants.py b/elections2021/constants.py index ec2ca0a4fc55455b43ac6f6b0363fea62c5f8a44..1e2b68f93b1d36647e5e78920ec4916f873e82c2 100644 --- a/elections2021/constants.py +++ b/elections2021/constants.py @@ -35,15 +35,53 @@ RICH_TEXT_FEATURES = [ ] ARTICLES_PER_PAGE = 9 +TOP_CANDIDATES_NUM = 12 + +REGION_JHC = "JHC" +REGION_JHM = "JHM" +REGION_KVK = "KVK" +REGION_KHK = "KHK" +REGION_LBK = "LBK" +REGION_MSK = "MSK" +REGION_OLK = "OLK" +REGION_PAK = "PAK" +REGION_PLK = "PLK" +REGION_PHA = "PHA" +REGION_STC = "STC" +REGION_ULK = "ULK" +REGION_VYS = "VYS" +REGION_ZLK = "ZLK" + +REGION_CHOICES = ( + (REGION_JHC, "Jihočeský kraj"), + (REGION_JHM, "Jihomoravský kraj"), + (REGION_KVK, "Karlovarský kraj"), + (REGION_KHK, "Královéhradecký kraj"), + (REGION_LBK, "Liberecký kraj"), + (REGION_MSK, "Moravskoslezský kraj"), + (REGION_OLK, "Olomoucký kraj"), + (REGION_PAK, "Pardubický kraj"), + (REGION_PLK, "Plzeňský kraj"), + (REGION_PHA, "Praha"), + (REGION_STC, "Středočeský kraj"), + (REGION_ULK, "Ústecký kraj"), + (REGION_VYS, "Vysočina"), + (REGION_ZLK, "Zlínský kraj"), +) + +PIRATES = "pirati" +STAN = "stan" +PARTY_CHOICES = ((PIRATES, "Piráti"), (STAN, "STAN")) +PARTY_NAME = {PIRATES: "Pirátská strana", STAN: "Starostové a nezávislí"} # cílovky CHILDLESS = "childless" -PARENT = "parent" +PARENTS = "parents" MATURE = "mature" -GRANDPARENT = "grandparent" -WORKING_SENIOR = "working_senior" -STUDENT = "student" +SENIORS = "seniors" +WORKING_SENIORS = "working_seniors" +STUDENTS = "students" SELF_EMPLOYED = "self_employed" SOCIALLY_WEAK = "socially_weak" @@ -59,11 +97,11 @@ EDUCATION = "education" TARGET_CHOICES = ( (CHILDLESS, "bezdětní"), - (PARENT, "rodiče"), - (MATURE, "zralý"), - (GRANDPARENT, "prarodiče"), - (WORKING_SENIOR, "pracující senioři"), - (STUDENT, "studenti"), + (PARENTS, "rodiče"), + (MATURE, "zralí"), + (SENIORS, "senioři"), + (WORKING_SENIORS, "pracující senioři"), + (STUDENTS, "studenti"), (SELF_EMPLOYED, "OSVČ"), (SOCIALLY_WEAK, "sociálně slabí"), (NATURE, "příroda"), diff --git a/elections2021/migrations/0002_elections2021candidatepage_elections2021candidateslistpage_elections2021candidatesmappage.py b/elections2021/migrations/0002_elections2021candidatepage_elections2021candidateslistpage_elections2021candidatesmappage.py new file mode 100644 index 0000000000000000000000000000000000000000..bf92e9e070caf3b0ea6d11288a30b17b28116ac7 --- /dev/null +++ b/elections2021/migrations/0002_elections2021candidatepage_elections2021candidateslistpage_elections2021candidatesmappage.py @@ -0,0 +1,233 @@ +# Generated by Django 3.1.7 on 2021-05-04 22:31 + +import django.db.models.deletion +import wagtail.core.fields +import wagtailmetadata.models +from django.db import migrations, models + +import shared.models + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailcore", "0060_fix_workflow_unique_constraint"), + ("wagtailimages", "0023_add_choose_permissions"), + ("elections2021", "0001_initial"), + ] + + operations = [ + migrations.CreateModel( + name="Elections2021CandidatesMapPage", + 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", + ), + ), + ( + "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": "Kandidáti mapa", + }, + bases=( + shared.models.SubpageMixin, + wagtailmetadata.models.WagtailImageMetadataMixin, + "wagtailcore.page", + models.Model, + ), + ), + migrations.CreateModel( + name="Elections2021CandidatesListPage", + 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", + ), + ), + ( + "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": "Kandidáti", + }, + bases=( + shared.models.SubpageMixin, + wagtailmetadata.models.WagtailImageMetadataMixin, + "wagtailcore.page", + models.Model, + ), + ), + migrations.CreateModel( + name="Elections2021CandidatePage", + 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", + ), + ), + ( + "party", + models.CharField( + choices=[("pirati", "Piráti"), ("stan", "STAN")], + default="pirati", + max_length=6, + verbose_name="strana", + ), + ), + ( + "region", + models.CharField( + choices=[ + ("JHC", "Jihočeský kraj"), + ("JHM", "Jihomoravský kraj"), + ("KVK", "Karlovarský kraj"), + ("KHK", "Královéhradecký kraj"), + ("LBK", "Liberecký kraj"), + ("MSK", "Moravskoslezský kraj"), + ("OLK", "Olomoucký kraj"), + ("PAK", "Pardubický kraj"), + ("PLK", "Plzeňský kraj"), + ("PHA", "Praha"), + ("STC", "Středočeský kraj"), + ("ULK", "Ústecký kraj"), + ("VYS", "Vysočina"), + ("ZLK", "Zlínský kraj"), + ], + max_length=3, + verbose_name="kraj", + ), + ), + ("number", models.IntegerField(verbose_name="pořadí")), + ("age", models.IntegerField(verbose_name="věk")), + ( + "occupation", + models.CharField(max_length=255, verbose_name="povolání"), + ), + ("city", models.CharField(max_length=100, verbose_name="bydliště")), + ( + "resume", + wagtail.core.fields.RichTextField(verbose_name="medailonek"), + ), + ( + "email", + models.EmailField( + blank=True, max_length=254, null=True, verbose_name="email" + ), + ), + ( + "phone", + models.CharField( + blank=True, max_length=20, null=True, verbose_name="telefon" + ), + ), + ( + "facebook_url", + models.URLField(blank=True, null=True, verbose_name="Facebook URL"), + ), + ( + "twitter_url", + models.URLField(blank=True, null=True, verbose_name="Twitter URL"), + ), + ( + "instagram_url", + models.URLField( + blank=True, null=True, verbose_name="Instagram URL" + ), + ), + ( + "website_url", + models.URLField( + blank=True, null=True, verbose_name="webová stránka" + ), + ), + ( + "photo", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="wagtailimages.image", + verbose_name="foto", + ), + ), + ( + "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": "Detail kandidáta", + }, + bases=( + shared.models.SubpageMixin, + wagtailmetadata.models.WagtailImageMetadataMixin, + "wagtailcore.page", + models.Model, + ), + ), + ] diff --git a/elections2021/models.py b/elections2021/models.py index 971f1f67536d81e72eb9b4e94d4632620cae3ba4..7a65cb412c3d918ec44933fc234bd472d38ddabd 100644 --- a/elections2021/models.py +++ b/elections2021/models.py @@ -1,9 +1,19 @@ +from collections import defaultdict +from functools import cached_property + +from django import forms from django.core.paginator import Paginator from django.db import models +from django.utils.translation import gettext_lazy from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey from taggit.models import TaggedItemBase -from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel +from wagtail.admin.edit_handlers import ( + FieldPanel, + HelpPanel, + MultiFieldPanel, + StreamFieldPanel, +) from wagtail.core import blocks from wagtail.core.fields import RichTextField, StreamField from wagtail.core.models import Page @@ -12,12 +22,19 @@ from wagtailmetadata.models import MetadataPageMixin from shared.models import ArticleMixin, SubpageMixin from shared.utils import get_subpage_url +from tuning import help from .constants import ( ARTICLES_PER_PAGE, + PARTY_CHOICES, + PARTY_NAME, + PIRATES, + REGION_CHOICES, + REGION_PHA, RICH_TEXT_FEATURES, STYLE_CHOICES, STYLE_CSS, + TOP_CANDIDATES_NUM, WHITE, ) @@ -46,6 +63,8 @@ class Elections2021HomePage(Page, MetadataPageMixin): ### PANELS + # TODO promote_panels + settings_panels = [ FieldPanel("matomo_id"), StreamFieldPanel("header_links"), @@ -55,7 +74,11 @@ class Elections2021HomePage(Page, MetadataPageMixin): ### RELATIONS parent_page_types = [] - subpage_types = ["elections2021.Elections2021ArticlesPage"] + subpage_types = [ + "elections2021.Elections2021ArticlesPage", + "elections2021.Elections2021CandidatesListPage", + "elections2021.Elections2021CandidatesMapPage", + ] ### OTHERS @@ -66,11 +89,18 @@ class Elections2021HomePage(Page, MetadataPageMixin): def root_page(self): return self - @property + @cached_property def articles_page_url(self): - # TODO instance cache return get_subpage_url(self, Elections2021ArticlesPage) + @cached_property + def candidates_list_page_url(self): + return get_subpage_url(self, Elections2021CandidatesListPage) + + @cached_property + def candidates_map_page_url(self): + return get_subpage_url(self, Elections2021CandidatesMapPage) + class Elections2021ArticleTag(TaggedItemBase): content_object = ParentalKey( @@ -89,6 +119,8 @@ class Elections2021ArticlePage(ArticleMixin, SubpageMixin, MetadataPageMixin, Pa ### PANELS + # TODO promote_panels + content_panels = ArticleMixin.content_panels + [ FieldPanel("tags"), FieldPanel("card_style"), @@ -131,6 +163,8 @@ class Elections2021ArticlesPage(SubpageMixin, MetadataPageMixin, Page): ### PANELS + # TODO promote_panels + content_panels = Page.content_panels + [ImageChooserPanel("photo")] settings_panels = [] @@ -152,3 +186,192 @@ class Elections2021ArticlesPage(SubpageMixin, MetadataPageMixin, Page): ARTICLES_PER_PAGE, ).get_page(request.GET.get("page")) return context + + +class Elections2021CandidatesListPage(SubpageMixin, MetadataPageMixin, Page): + ### FIELDS + + photo = models.ForeignKey( + "wagtailimages.Image", + on_delete=models.PROTECT, + blank=True, + null=True, + verbose_name="hlavní fotka", + ) + + ### PANELS + + # TODO promote_panels + + content_panels = Page.content_panels + [ImageChooserPanel("photo")] + + settings_panels = [] + + ### RELATIONS + + parent_page_types = ["elections2021.Elections2021HomePage"] + subpage_types = ["elections2021.Elections2021CandidatePage"] + + ### OTHERS + + class Meta: + verbose_name = "Kandidáti" + + def get_context(self, request): + context = super().get_context(request) + + region_candidates_top = defaultdict(list) + region_candidates_bottom = defaultdict(list) + + candidates = ( + self.get_children() + .live() + .specific() + .order_by("elections2021candidatepage__number") + ) + + for can in candidates: + if len(region_candidates_top[can.region]) < TOP_CANDIDATES_NUM: + region_candidates_top[can.region].append(can) + else: + region_candidates_bottom[can.region].append(can) + + context["region_candidates_top"] = dict(region_candidates_top) + context["region_candidates_bottom"] = dict(region_candidates_bottom) + context["region_choices"] = REGION_CHOICES + context["region_codes"] = [code for code, _ in REGION_CHOICES] + + active_region = request.GET.get("kraj", REGION_PHA) + if active_region in context["region_codes"]: + context["active_region"] = active_region + else: + context["active_region"] = REGION_PHA + + return context + + +class Elections2021CandidatesMapPage(SubpageMixin, MetadataPageMixin, Page): + ### FIELDS + + photo = models.ForeignKey( + "wagtailimages.Image", + on_delete=models.PROTECT, + blank=True, + null=True, + verbose_name="hlavní fotka", + ) + + ### PANELS + + # TODO promote_panels + + content_panels = Page.content_panels + [ImageChooserPanel("photo")] + + settings_panels = [] + + ### RELATIONS + + parent_page_types = ["elections2021.Elections2021HomePage"] + subpage_types = [] + + ### OTHERS + + class Meta: + verbose_name = "Kandidáti mapa" + + +class Elections2021CandidatePage(SubpageMixin, MetadataPageMixin, Page): + ### FIELDS + + party = models.CharField( + "strana", choices=PARTY_CHOICES, default=PIRATES, max_length=6 + ) + region = models.CharField("kraj", choices=REGION_CHOICES, max_length=3) + number = models.IntegerField("pořadí") + age = models.IntegerField("věk") + occupation = models.CharField("povolání", max_length=255) + city = models.CharField("bydliště", max_length=100) + # TODO RICH_TEXT_FEATURES + resume = RichTextField("medailonek") + email = models.EmailField("email", null=True, blank=True) + phone = models.CharField("telefon", null=True, blank=True, max_length=20) + facebook_url = models.URLField("Facebook URL", blank=True, null=True) + twitter_url = models.URLField("Twitter URL", blank=True, null=True) + instagram_url = models.URLField("Instagram URL", blank=True, null=True) + website_url = models.URLField("webová stránka", blank=True, null=True) + photo = models.ForeignKey( + "wagtailimages.Image", + on_delete=models.PROTECT, + blank=True, + null=True, + verbose_name="foto", + ) + + ### PANELS + + content_panels = Page.content_panels + [ + MultiFieldPanel( + [ + FieldPanel("party", widget=forms.RadioSelect), + FieldPanel("region"), + FieldPanel("number"), + ], + "zařazení", + ), + MultiFieldPanel( + [ + FieldPanel("age"), + FieldPanel("occupation"), + FieldPanel("city"), + ], + "osobní údaje", + ), + ImageChooserPanel("photo"), + FieldPanel("resume"), + MultiFieldPanel( + [ + FieldPanel("email"), + FieldPanel("phone"), + FieldPanel("facebook_url"), + FieldPanel("twitter_url"), + FieldPanel("instagram_url"), + FieldPanel("website_url"), + ], + "kontakty", + ), + ] + + promote_panels = [ + MultiFieldPanel( + [ + FieldPanel("slug"), + FieldPanel("seo_title"), + FieldPanel("search_description"), + HelpPanel(help.build(help.NO_SEO_TITLE)), + ], + gettext_lazy("Common page configuration"), + ), + ] + + settings_panels = [] + + ### RELATIONS + + parent_page_types = ["elections2021.Elections2021CandidatesListPage"] + subpage_types = [] + + ### OTHERS + + class Meta: + verbose_name = "Detail kandidáta" + + def get_meta_image(self): + return self.photo + + @property + def party_name(self): + return PARTY_NAME[self.party] + + @property + def is_pirate(self): + return self.party == PIRATES diff --git a/elections2021/templates/elections2021/_candidate_card.html b/elections2021/templates/elections2021/_candidate_card.html new file mode 100644 index 0000000000000000000000000000000000000000..d197ba2c3218e0a0b028507de23b083ead8bd59a --- /dev/null +++ b/elections2021/templates/elections2021/_candidate_card.html @@ -0,0 +1,53 @@ +{% load static wagtailcore_tags wagtailimages_tags %} +<div class="candidate-card candidate-card--pirati-stan container-padding--zero sm:container-padding--auto "> + <div class="candidate-card__wrapper candidate-card-list__item-wrapper {% if not candidate.is_pirate %}candidate-card-list__item-wrapper--stan-candidate{% endif %}"> + <div class="card candidate-card__body elevation-0 hover:elevation-10 transition duration-200"> + <div class="candidate-card__avatar sm:pl-0"> + <div class="candidate-card__position">{{ candidate.number }}</div> + <a href="{% pageurl candidate %}" data-href="{% pageurl candidate %}"> + <div class="avatar avatar--sm sm:avatar--lg"> + {% image candidate.photo fill-112x112 %} + </div> + </a> + </div> + <div class="candidate-card__bio"> + <h1 class="head-heavy-xs"><a href="{% pageurl candidate %}" data-href="{% pageurl candidate %}">{{ candidate.title }}</a></h1> + <a href="mailto:{{ candidate.email }}" class="candidate-card__bio-item block mb-4">{{ candidate.email|default:"" }}</a> + <h2 class="candidate-card__bio-item">{{ candidate.occupation }}</h2> + <h2 class="head-allcaps-4xs mt-4">{{ candidate.city }}</h2> + </div> + <div class="candidate-card__affiliation"> + <div>{{ candidate.age }} let</div> + <div> + <div class="mr-2"> + {% if candidate.is_pirate %} + <img src="{% static "elections2021/images/logo-pirati-21px.svg" %}"> + {% else %} + <img src="{% static "elections2021/images/logo-stan-21px.svg" %}"> + {% endif %} + </div> + <span class="font-bold font-condensed">{{ candidate.party_name }}</span> + </div> + </div> + <div class="card__body candidate-card__social"> + <div class="social-icon-group space-x-2 "> + {% if candidate.facebook_url %} + <a href="{{ candidate.facebook_url }}" class="social-icon"><i class="ico--facebook"></i></a> + {% endif %} + {% if candidate.twitter_url %} + <a href="{{ candidate.twitter_url }}" class="social-icon"><i class="ico--twitter"></i></a> + {% endif %} + {% if candidate.instagram_url %} + <a href="{{ candidate.instagram_url }}" class="social-icon"><i class="ico--instagram"></i></a> + {% endif %} + {% if candidate.website_url %} + <a href="{{ candidate.website_url }}" class="social-icon"><i class="ico--home"></i></a> + {% endif %} + {% if candidate.email %} + <a href="mailto:{{ candidate.email }}" class="social-icon"><i class="ico--envelope"></i></a> + {% endif %} + </div> + </div> + </div> + </div> +</div> diff --git a/elections2021/templates/elections2021/base.html b/elections2021/templates/elections2021/base.html index 8760cceed5208d868a1388109d62d246bf0d063f..05d8f058e3a0508283c9312376529315c1e57b13 100644 --- a/elections2021/templates/elections2021/base.html +++ b/elections2021/templates/elections2021/base.html @@ -62,8 +62,8 @@ <li class="navbar-menu__item"> <ui-navbar-subitem label="Kandidáti" href="#"> <ul class="navbar-menu__submenu"> - <li><a href="#" data-href="#" class="navbar-menu__link">Výpis kandidátů</a></li> - <li><a href="#" data-href="#" class="navbar-menu__link">Výpis kandidátů podle mapy</a></li> + <li><a href="{{ page.root_page.candidates_list_page_url }}" data-href="{{ page.root_page.candidates_list_page_url }}" class="navbar-menu__link">Výpis kandidátů</a></li> + <li><a href="{{ page.root_page.candidates_map_page_url }}" data-href="{{ page.root_page.candidates_map_page_url }}" class="navbar-menu__link">Výpis kandidátů podle mapy</a></li> </ul> </ui-navbar-subtitem> </li> @@ -114,7 +114,7 @@ <a href="{{ page.root_page.articles_page_url }}">Aktality</a> </li> <li> - <a href="#">Kandidáti</a> + <a href="{{ page.root_page.candidates_list_page_url }}">Kandidáti</a> </li> <li> <a href="#">Programové body</a> diff --git a/elections2021/templates/elections2021/elections2021_candidate_page.html b/elections2021/templates/elections2021/elections2021_candidate_page.html new file mode 100644 index 0000000000000000000000000000000000000000..b037d42ce140e58d04a16a4e4cb98285904db6b8 --- /dev/null +++ b/elections2021/templates/elections2021/elections2021_candidate_page.html @@ -0,0 +1,90 @@ +{% extends "elections2021/base.html" %} +{% load static wagtailcore_tags wagtailimages_tags %} + +{% block content %} +<article class="hero hero--image pt-24 pb-20 lg:pt-28 pb-10 candidate-detail__hero "> + <div class="container container--default text-center lg:text-left"> + <a href="{{ page.root_page.candidates_list_page_url }}?kraj={{ page.region }}" class="btn text-sm btn--hoveractive btn--to-black"> + <div class="btn__body leading-5 bg-acidgreen text-black hover:text-white px-10 py-3">zpět na výpis</div> + </a> + <h1 class="head-alt-md md:head-alt-xl mt-9 text-black">{{ page.title }}</h1> + </div> +</article> + +<div class="container container--default py-8 lg:pb-24"> + <main> + <div class="flex flex-col lg:flex-row lg:space-x-8 xl:space-x-16"> + <section class="lg:w-3/5 xl:w-2/3"> + <div class="content-block w-full"> + {{ page.resume|richtext }} + </div> + </section> + <section class="lg:w-2/5 xl:w-1/3 pt-8 lg:pt-0 order-first lg:order-last candidate-detail__sidebar"> + <div class="container-padding--zero lg:card lg:elevation-10 lg:container-padding--auto"> + <div class="card__body p-4 lg:p-8"> + <div class="text-center mb-8"> + <div class="avatar relative avatar--2xl lg:avatar--3xl avatar--bordered candidate-detail__avatar"> + <div class="avatar-candidate-position"> + <span class="font-alt text-2xl">{{ page.number }}</span> + </div> + {% image page.photo fill-224x224 %} + </div> + </div> + <div class="flex items-center"> + <div class="mr-2"> + {% if page.is_pirate %} + <img src="{% static "elections2021/images/logo-pirati-21px.svg" %}"> + {% else %} + <img src="{% static "elections2021/images/logo-stan-21px.svg" %}"> + {% endif %} + </div> + <span class="font-bold font-condensed">{{ page.party_name }}</span> + </div> + <hr> + <div> + <p class="font-bold font-condensed text-base">{{ page.get_region_display }}</p> + <p class="text-sm mt-1">{{ page.city }}</p> + </div> + <hr> + <div class="space-y-4"> + <div> + <p class="text-sm"> + <i class="ico--info text-xs"></i> {{ page.age }} let + </p> + </div> + <div> + <p class="text-sm"> + <i class="ico--info text-xs"></i> {{ page.occupation }} + </p> + </div> + </div> + <div> + <hr> + <div class="space-y-4"> + <div> + <div class="social-icon-group space-x-2 text-lg"> + {% if page.facebook_url %} + <a href="{{ page.facebook_url }}" class="social-icon"><i class="ico--facebook"></i></a> + {% endif %} + {% if page.twitter_url %} + <a href="{{ page.twitter_url }}" class="social-icon"><i class="ico--twitter"></i></a> + {% endif %} + {% if page.instagram_url %} + <a href="{{ page.instagram_url }}" class="social-icon"><i class="ico--instagram"></i></a> + {% endif %} + {% if page.website_url %} + <a href="{{ page.website_url }}" class="social-icon"><i class="ico--home"></i></a> + {% endif %} + {% if page.email %} + <a href="mailto:{{ page.email }}" class="social-icon"><i class="ico--envelope"></i></a> + {% endif %} + </div> + </div> + </div> + </div> + </div> + </div></section> + </div> + </main> +</div> +{% endblock %} diff --git a/elections2021/templates/elections2021/elections2021_candidates_list_page.html b/elections2021/templates/elections2021/elections2021_candidates_list_page.html new file mode 100644 index 0000000000000000000000000000000000000000..6a5e9024db53d7f3e2c7b6be6ce84b48c0340549 --- /dev/null +++ b/elections2021/templates/elections2021/elections2021_candidates_list_page.html @@ -0,0 +1,135 @@ +{% extends "elections2021/base.html" %} +{% load static wagtailcore_tags wagtailimages_tags %} + +{% block content %} +<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-2 lg:grid-cols-7 items-center 2xl:mx-auto"> + <div class="lg:row-span-1 lg:col-span-4 order-1 pt-14 md:pr-20"> + <h1 class="head-alt-md sm:head-alt-lg max-w-xs">{{ page.title }}</h1> + </div> + <div class="lg:row-span-1 lg:col-span-4 order-3 pb-14 md:pr-20"> + <div class="hidden md:block pt-8"> + <div class="switch"> + <a class="switch__item switch__item--active">seznam</a> + <a href="{{ page.root_page.candidates_map_page_url }}" class="switch__item">mapa</a> + </div> + </div> + </div> + <div class="hidden lg:block lg:row-span-2 lg:col-span-3 order-2 h-full 2xl:absolute 2xl:right-0 2xl:w-1/3"> + {% image page.photo fill-618x256 as img %} + <img class="object-cover w-full h-full" src="{{ img.url }}"> + </div> + </div> +</article> + +<div class="container container--default py-8 lg:py-24"> + <section class="text-center relative"> + <h1 class="head-alt-md pt-1 mb-8">Výpis kandidátů</h1> + + <div class="select md:absolute left-0 top-0 text-white w-full md:w-auto inline-flex md:float-left mb-8 md:mb-0"> + <select id="region_select" class="select__control form-field__control bg-black" data-chosen=""> + {% for code, name in region_choices %} + <option value="{{ code }}" {% if code == active_region %}selected=""{% endif %}>{{ name }}</option> + {% endfor %} + </select> + </div> + + <main class="md:mt-20"> + + {% for code, candidates in region_candidates_top.items %} + <div id="candidates_top_{{ code }}" {% if code != active_region %}class="hidden"{% endif %}> + <div class="candidate-card-list grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"> + {% for candidate in candidates %} + {% include "elections2021/_candidate_card.html" %} + {% endfor %} + </div> + </div> + {% endfor %} + + {% for code, candidates in region_candidates_bottom.items %} + <div id="candidates_bottom_{{ code }}" {% if code != active_region %}class="hidden"{% endif %}> + <div class="candidate-table container-padding--zero lg:container-padding--auto pt-8"> + {% for candidate in candidates %} + <a href="{% pageurl candidate %}" data-href="{% pageurl candidate %}" class="candidate-table-row"> + <div class="candidate-table-row__position head-allcaps-heavy-2xs text-right">{{ candidate.number }}</div> + <div class="avatar candidate-table-row__avatar"> + {% image candidate.photo fill-40x40 %} + </div> + <div class="candidate-table-row__name head-heavy-2xs font-bold">{{ candidate.title }}</div> + <div class="candidate-table-row__bio font-condensed">{{ candidate.age }} let, {{ candidate.occupation }}, {{ candidate.city }}</div> + <div class="candidate-table-row__affiliation"> + <div class="w-6 mr-2"> + {% if candidate.is_pirate %} + <img src="{% static "elections2021/images/logo-pirati-21px.svg" %}"> + {% else %} + <img src="{% static "elections2021/images/logo-stan-21px.svg" %}"> + {% endif %} + </div> + <span class="font-bold font-condensed">{{ candidate.party_name }}</span> + </div> + </a> + {% endfor %} + </div> + </div> + {% endfor %} + + <script> + var codes = ['{{ region_codes|join:"','" }}']; + var regionSelect = document.getElementById('region_select'); + regionSelect.addEventListener('change', function(e) { + var activeCode = this.value; + for (var i = 0; i < codes.length; i++) { + var code = codes[i]; + var classValue = (code == activeCode) ? '' : 'hidden'; + var top = document.getElementById('candidates_top_' + code); + var bottom = document.getElementById('candidates_bottom_' + code); + if (top !== null) { + top.setAttribute('class', classValue); + } + if (bottom !== null) { + bottom.setAttribute('class', classValue); + } + } + window.history.replaceState('', '', '?kraj=' + activeCode); + }); + </script> + + {% comment %} + <div class="pt-11 text-center"> + <button class="btn btn--icon showfulltable text-xl btn--hoveractive btn--to-black"> + <div class="btn__body-wrap"> + <div class="btn__body py-4 px-11 leading-5 bg-acidgreen text-black hover:text-white">Call to action</div> + <div class="btn__icon "> + <i class="ico--chevron-right"></i> + </div> + </div> + </button> + </div> + + <script> + //collapse toggle + //assumes only one present on page + var anchorShowFull = document.getElementsByClassName('showfulltable'); + + if (anchorShowFull !== null) { + + for (var i = 0; i < anchorShowFull.length; i++) { + anchorShowFull[i].addEventListener('click', function(e) { + e.preventDefault(); + var candidatestable = document.getElementsByClassName("candidate-table"); + //if fadeout + //candidatestable[0].classList.remove("candidate-table--fadeout"); + var collapsepart = document.getElementsByClassName("candidates-list-collapsing-part"); + collapsepart[0].style.maxHeight = collapsepart[0].scrollHeight + "px"; + this.remove(); + }); + } + } + </script> + {% endcomment %} + + </main> + </section> +</div> + +{% endblock %}