From 1f3038ebbc67dccac8c6dcb655bfb315529404fc Mon Sep 17 00:00:00 2001 From: Simon Caminada Date: Tue, 20 Mar 2018 19:50:59 +0100 Subject: [PATCH] nav and notification fixes --- private/js/modules/navigation.js | 1 + private/js/modules/notifications.js | 13 ++ private/js/modules/plugins/timetable.js | 2 + private/scss/main.scss | 1 + private/scss/modules/_content.scss | 10 +- private/scss/modules/_header.scss | 48 +++++- private/scss/modules/_navigation.scss | 13 ++ private/scss/modules/_notification.scss | 95 +++++++++++ private/scss/modules/_search.scss | 4 +- private/scss/modules/plugins/_form.scss | 2 +- .../modules/plugins/_journey_calculator.scss | 2 +- private/scss/modules/plugins/_slider.scss | 22 +-- settings.py | 1 + src/project/admin.py | 7 +- src/project/context_processors.py | 6 + src/project/models.py | 35 ++++ src/project/templates/main.html | 159 +++++++++++------- src/project/templates/project/assets/bell.svg | 4 + src/project/templates/project/content.html | 4 +- .../project/includes/navigation.html | 11 +- 20 files changed, 350 insertions(+), 90 deletions(-) create mode 100644 private/js/modules/notifications.js create mode 100644 private/scss/modules/_notification.scss create mode 100644 src/project/templates/project/assets/bell.svg diff --git a/private/js/modules/navigation.js b/private/js/modules/navigation.js index 5f56fa2..81b7c40 100644 --- a/private/js/modules/navigation.js +++ b/private/js/modules/navigation.js @@ -84,6 +84,7 @@ $(function() { function open_navigation() { window.timetable_can_scroll = false; window.navigation_is_open = true; + $body.removeClass('notification_open'); $navigation.one(window.transitionend, function() { window.requestAnimationFrame(function() { diff --git a/private/js/modules/notifications.js b/private/js/modules/notifications.js new file mode 100644 index 0000000..17f5a1c --- /dev/null +++ b/private/js/modules/notifications.js @@ -0,0 +1,13 @@ +$(function() { + var $body = $('body'); + + $body.on('click', '.header__button--notification', function(event) { + event.preventDefault(); + $body.toggleClass('notification_open'); + }); + + $body.on('click', '.notification__close', function(event) { + event.preventDefault(); + $body.removeClass('notification_open'); + }); +}); \ No newline at end of file diff --git a/private/js/modules/plugins/timetable.js b/private/js/modules/plugins/timetable.js index 6ac015b..bbdc82e 100644 --- a/private/js/modules/plugins/timetable.js +++ b/private/js/modules/plugins/timetable.js @@ -19,6 +19,7 @@ $(function() { if (!window.navigation_is_open) { if (activated) { if ($(window).scrollTop() < $(window).height() * 0.05 && window.timetable_can_scroll) { + $body.removeClass('notification_open'); window.prevent_scroll_calc = true; $timetable.attr('data-active', 0); $timetable.removeClass('active'); @@ -26,6 +27,7 @@ $(function() { } } else { if ($(window).scrollTop() > $(window).height() * 0.05 && window.timetable_can_scroll) { + $body.removeClass('notification_open'); init_timetable_items(); } } diff --git a/private/scss/main.scss b/private/scss/main.scss index 3ec23f6..36be604 100644 --- a/private/scss/main.scss +++ b/private/scss/main.scss @@ -5,6 +5,7 @@ @import "_typography.scss"; @import "_layout.scss"; @import "modules/_header.scss"; +@import "modules/_notification.scss"; @import "modules/_footer.scss"; @import "modules/_search.scss"; @import "modules/_navigation.scss"; diff --git a/private/scss/modules/_content.scss b/private/scss/modules/_content.scss index 9050ec6..cbf7b11 100644 --- a/private/scss/modules/_content.scss +++ b/private/scss/modules/_content.scss @@ -123,14 +123,16 @@ $max-width: 100%; } .content__navigation__title { - font-size: em(16px); - color: $green; + padding-top: em(10px); + font-size: em(18px); + color: $gray; letter-spacing: 0.02em; text-transform: uppercase; line-height: 1.35; display: block; width: 100%; - font-weight: 900; + font-weight: 700; + margin-bottom: em(20px); } .content__navigation__content { @@ -161,7 +163,7 @@ $max-width: 100%; } .content__navigation__anchor { - font-size: em(16px); + font-size: em(14px); color: $gray; letter-spacing: 0.02em; text-transform: uppercase; diff --git a/private/scss/modules/_header.scss b/private/scss/modules/_header.scss index 62cce2b..98b89de 100644 --- a/private/scss/modules/_header.scss +++ b/private/scss/modules/_header.scss @@ -11,7 +11,7 @@ z-index: 506; overflow: hidden; transition: z-index 0s 1s; - will-change: transform, top; + will-change: transform; .search_open &, .navigation_open & { z-index: 909; transition: z-index 0s; @@ -186,11 +186,8 @@ .search_open &, .navigation_open & { transform: translateY(-100%); } - @media screen and (max-width: $small_breakpoint) { - padding: 0 em(5px); - } - @media screen and (max-width: $tiny_breakpoint) { - padding: 0; + @media screen and (max-width: $medium_breakpoint) { + display: none; } } @@ -346,6 +343,45 @@ } } +@keyframes ring { + 0% { + transform: rotate(0); + } + 10% { + transform: rotate(-10deg); + } + 20% { + transform: rotate(10deg); + } + 30% { + transform: rotate(-10deg); + } + 40% { + transform: rotate(10deg); + } + 50% { + transform: rotate(0); + } +} + +.header__button--notification { + font-size: 0; + padding-left: 0; + .header__button__icon { + transform-origin: 50% 30%; + animation: ring 2s $easeOutQuad infinite; + } + svg { + transform: none; + transition: transform 0.3s $easeOutQuart; + } + &:hover { + svg { + transform: scale(1.12); + } + } +} + .header__button__icon { width: em(32px); height: em(32px); diff --git a/private/scss/modules/_navigation.scss b/private/scss/modules/_navigation.scss index 5b1bdff..636b66f 100644 --- a/private/scss/modules/_navigation.scss +++ b/private/scss/modules/_navigation.scss @@ -59,6 +59,19 @@ } } +.navigation__extra { + position: relative; + width: 100%; + min-height: em(50px); + .header__languages { + position: absolute; + top: 0; + right: 0; + transform: none; + display: block; + } +} + .navigation__main { height: 100%; width: 100%; diff --git a/private/scss/modules/_notification.scss b/private/scss/modules/_notification.scss new file mode 100644 index 0000000..0a70f13 --- /dev/null +++ b/private/scss/modules/_notification.scss @@ -0,0 +1,95 @@ +.notification { + position: fixed; + top: em(80px); + right: em(30px); + width: em(260px); + z-index: 1000; + height: auto; + background: $white; + box-shadow: 0 0 em(30px) rgba($black, 0.2); + transform: scale(0); + opacity: 0; + transform-origin: 23% 5%; + transition: transform 0.3s $easeOutQuad, opacity 0.3s $easeOutQuad; + &:before { + content: ''; + display: block; + background: $white; + z-index: -2; + position: absolute; + top: em(-10px); + right: em(187px); + width: em(20px); + height: em(20px); + transform: rotate(45deg); + box-shadow: 0 0 30px rgba($black, 0.2); + } + .notification_open & { + opacity: 1; + transform: none; + } + .cms-toolbar-expanded & { + margin-top: 46px; + } + @media screen and (max-width: $small_breakpoint) { + transform-origin: 36% 5%; + &:before { + right: em(157px); + } + } +} + +.notification__content { + width: 100%; + height: auto; + padding: em(20px) em(30px); + position: relative; + overflow: auto; + max-height: 70vh; + background: $white; +} + +.notification__title { + line-height: 1.35; + color: $green; + font-size: em(18px); + font-weight: 700; + padding-right: em(55px); + margin-bottom: em(10px); +} + +.notification__text { + line-height: 1.4; + color: $dark_gray; + font-size: em(14px); +} + +.notification__button { + margin-top: em(20px); + height: em(38px) !important; + line-height: em(36px) !important; + font-size: em(12px) !important; + svg { + width: em(24px) !important; + height: em(24px) !important; + margin: em(7px) 0 !important; + } +} + +.notification__close { + position: absolute; + top: 0; + right: 0; + padding: em(25px); + svg { + width: em(20px); + height: em(20px); + fill: $dark_gray; + transition: fill 0.3s; + } + &:hover { + svg { + fill: $near_black; + } + } +} \ No newline at end of file diff --git a/private/scss/modules/_search.scss b/private/scss/modules/_search.scss index 63d9160..42a0db4 100644 --- a/private/scss/modules/_search.scss +++ b/private/scss/modules/_search.scss @@ -52,7 +52,7 @@ top: 0; transform: none; } - input { + input[type="text"] { display: block; width: 100%; height: em(90px); @@ -97,7 +97,7 @@ } } @media screen and (max-width: $large_breakpoint) { - input { + input[type="text"] { height: em(60px); font-size: em(23px); text-indent: em(17px); diff --git a/private/scss/modules/plugins/_form.scss b/private/scss/modules/plugins/_form.scss index 4ddd31a..6b5aede 100644 --- a/private/scss/modules/plugins/_form.scss +++ b/private/scss/modules/plugins/_form.scss @@ -58,7 +58,7 @@ background: $green; border-radius: 0; color: $white; - font-weight: 900; + font-weight: 700; cursor: pointer; letter-spacing: 0.02em; position: relative; diff --git a/private/scss/modules/plugins/_journey_calculator.scss b/private/scss/modules/plugins/_journey_calculator.scss index f615b91..5eb7794 100644 --- a/private/scss/modules/plugins/_journey_calculator.scss +++ b/private/scss/modules/plugins/_journey_calculator.scss @@ -36,7 +36,7 @@ padding-right: em(105px); transition: padding 0.3s ease-in-out; will-change: padding; - input { + input[type="text"] { border: none; background: $white; height: em(45px); diff --git a/private/scss/modules/plugins/_slider.scss b/private/scss/modules/plugins/_slider.scss index 50eaf7f..a2637bb 100644 --- a/private/scss/modules/plugins/_slider.scss +++ b/private/scss/modules/plugins/_slider.scss @@ -131,7 +131,8 @@ top: 0; left: 0; right: em(180px); - bottom: 0; + padding-bottom: 56%; + max-height: 100%; z-index: -1; @media screen and (max-width: $medium_breakpoint) { right: 10%; @@ -173,7 +174,7 @@ font-size: 0; white-space: nowrap; overflow: hidden; - padding-bottom: em(40px); + padding-bottom: em(50px); @media screen and (max-width: $medium_breakpoint) { width: 90%; } @@ -263,28 +264,27 @@ .slider__text__item__email { display: block; text-decoration: none; - width: em(70px); - height: em(70px); + width: 70px; + height: 70px; background: $white; border-radius: 50%; position: absolute; - bottom: em(-30px); + bottom: -30px; left: 20%; transform: none; - transition: transform 0.2s ease-in-out, box-shadow 0.2s; - box-shadow: 0 0 em(30px) rgba($black, 0); + transition: transform 0.2s ease-in-out; + box-shadow: 0 0 30px rgba($black, 0.1); text-align: center; - line-height: em(69px); + line-height: 69px; svg { display: inline-block; fill: $green; - width: em(30px); - height: em(30px); + width: 30px; + height: 30px; vertical-align: middle; margin-top: -2px; } &:hover { transform: scale(1.1); - box-shadow: 0 0 em(30px) rgba($black, 0.1); } } \ No newline at end of file diff --git a/settings.py b/settings.py index 573b1ed..2a8b9fb 100644 --- a/settings.py +++ b/settings.py @@ -38,6 +38,7 @@ MIDDLEWARE_CLASSES.extend([ TEMPLATES[0]['OPTIONS']['context_processors'] += [ 'project.context_processors.search_form', + 'project.context_processors.notification', 'project.context_processors.new_page_amount', ] diff --git a/src/project/admin.py b/src/project/admin.py index cc0d1c1..f3c0021 100644 --- a/src/project/admin.py +++ b/src/project/admin.py @@ -3,7 +3,7 @@ from django.contrib import admin from cms.extensions import PageExtensionAdmin from parler.admin import TranslatableAdmin -from project.models import ImageExtension, SliderItemQualification +from project.models import ImageExtension, SliderItemQualification, Notification @admin.register(ImageExtension) @@ -14,3 +14,8 @@ class ImageExtensionAdmin(PageExtensionAdmin): @admin.register(SliderItemQualification) class SliderItemQualificationAdmin(TranslatableAdmin): pass + + +@admin.register(Notification) +class NotificationAdmin(TranslatableAdmin): + pass diff --git a/src/project/context_processors.py b/src/project/context_processors.py index b986d38..8a7d5ca 100644 --- a/src/project/context_processors.py +++ b/src/project/context_processors.py @@ -1,11 +1,17 @@ from cms.models import Page from haystack.forms import ModelSearchForm +from project.models import Notification + def search_form(request): return {'search_form': ModelSearchForm} +def notification(request): + return {'notification': Notification.objects.filter(published=True).first()} + + def new_page_amount(request): tracked_pages = ['news', 'calendar'] context = {} diff --git a/src/project/models.py b/src/project/models.py index a6d66ce..6fa527d 100644 --- a/src/project/models.py +++ b/src/project/models.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +from cms.models.fields import PageField from cms.models.pluginmodel import CMSPlugin from django.db import models from itertools import chain @@ -54,6 +55,38 @@ class Video(CMSPlugin): return str(self.vimeo_id) +class Notification(TranslatableModel): + translations = TranslatedFields( + title=models.CharField('Titel', max_length=256, null=True, blank=True), + text=models.TextField('Text', null=True, blank=True), + cta=models.CharField('CTA Text', max_length=256, null=True, blank=True) + ) + page = PageField(verbose_name='Seite') + published = models.BooleanField(verbose_name='Veröffentlicht', default=True) + updated = models.DateTimeField(verbose_name='Aktualisiert', auto_now=True) + + class Meta: + verbose_name = 'Benachrichtigung' + verbose_name_plural = 'Benachrichtigungen' + + def __str__(self): + return self.get_title + + @property + def get_title(self): + if self.title: + return self.title + else: + return self.page.get_page_title() + + @property + def get_text(self): + if self.text: + return self.text + else: + return self.page.get_meta_description() + + class SliderItemQualification(TranslatableModel): translations = TranslatedFields( name=models.CharField('name', max_length=256) @@ -61,6 +94,8 @@ class SliderItemQualification(TranslatableModel): ordering = models.IntegerField(verbose_name='Sortierung', default=5) class Meta: + verbose_name = 'Slider Qualifikation' + verbose_name_plural = 'Slider Qualifikationen' ordering = ['ordering'] def __str__(self): diff --git a/src/project/templates/main.html b/src/project/templates/main.html index 8e69cc2..a08a470 100644 --- a/src/project/templates/main.html +++ b/src/project/templates/main.html @@ -27,80 +27,115 @@ {{ ALDRYN_SNAKE.render_head }} -{% cms_toolbar %} - - - - - - - - -{% url 'search' as search_url %} - -
- {% trans 'Stärken stärken. Lernen lernen.' %} - - - {% trans 'Suche' %} - - {% include 'project/assets/search.svg' %} - + {% cms_toolbar %} + + + + + + {% url 'search' as search_url %} - {% with request.get_full_path as current_url %} - - {% trans 'Menü' %} + + {% if notification %} + + {% endif %} + +
+ {% trans 'Stärken stärken. Lernen lernen.' %} +
    + {% for lang in LANGUAGES %} +
  • + {{ lang.0 }} +
  • + {% endfor %} +
+ + {% if notification %} + + {% trans 'Aktuell' %} + + {% include 'project/assets/bell.svg' %} + + + {% endif %} + + + {% trans 'Suche' %} - {% include 'project/assets/menu.svg' %} + {% include 'project/assets/search.svg' %} - {% endwith %} -
- {% include 'project/includes/meta_navigation.html' %} + {% url 'search' as search_url %} + {% with request.get_full_path as current_url %} + + {% trans 'Menü' %} + + {% include 'project/assets/menu.svg' %} + + + {% endwith %} + +
+ {% include 'project/includes/meta_navigation.html' %} +
-
-
- {% block content %} - {% placeholder 'content' %} - {% endblock %} -
- -