From f069baa260c759de0fc255a4e5db82e312337fad Mon Sep 17 00:00:00 2001
From: mipel <hadunan@gmail.com>
Date: Mon, 5 Jul 2021 14:49:32 +0200
Subject: [PATCH] Landing page

* started to implement a landing page
* started news implementation
---
 konova/admin.py                    |  21 +++++++
 konova/enums.py                    |  11 +++-
 konova/models.py                   |  13 +++++
 konova/settings.py                 |   8 +++
 konova/static/css/konova.css       |  18 ++++++
 konova/templates/konova/home.html  |  74 +++++++++++-------------
 konova/templatetags/__init__.py    |   7 +++
 konova/templatetags/ksp_filters.py |  28 +++++++++
 konova/views.py                    |  15 ++++-
 locale/de/LC_MESSAGES/django.mo    | Bin 3396 -> 3436 bytes
 locale/de/LC_MESSAGES/django.po    |  89 ++++++++++++++++++-----------
 templates/base.html                |   4 +-
 12 files changed, 213 insertions(+), 75 deletions(-)
 create mode 100644 konova/admin.py
 create mode 100644 konova/templatetags/__init__.py
 create mode 100644 konova/templatetags/ksp_filters.py

diff --git a/konova/admin.py b/konova/admin.py
new file mode 100644
index 00000000..a5c81175
--- /dev/null
+++ b/konova/admin.py
@@ -0,0 +1,21 @@
+"""
+Author: Michel Peltriaux
+Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
+Contact: michel.peltriaux@sgdnord.rlp.de
+Created on: 05.07.21
+
+"""
+from django.contrib import admin
+
+from konova.models import ServerMessage
+
+
+class ServerMessageAdmin(admin.ModelAdmin):
+    list_display = [
+        "id",
+        "subject",
+        "publish_on",
+        "is_active",
+    ]
+
+admin.site.register(ServerMessage, ServerMessageAdmin)
diff --git a/konova/enums.py b/konova/enums.py
index 8cb545c6..cabb9788 100644
--- a/konova/enums.py
+++ b/konova/enums.py
@@ -37,4 +37,13 @@ class UnitEnum(BaseEnum):
     qkm = "qkm"
     ha = "ha"
 
-    st = "St."  # pieces
\ No newline at end of file
+    st = "St."  # pieces
+
+
+class ServerMessageImportance(BaseEnum):
+    """
+    Defines importance levels for server messages
+    """
+    DEFAULT = "DEFAULT"
+    INFO = "INFO"
+    WARNING = "WARNING"
diff --git a/konova/models.py b/konova/models.py
index c7348cbc..bb7eebb2 100644
--- a/konova/models.py
+++ b/konova/models.py
@@ -11,6 +11,8 @@ from django.contrib.auth.models import User
 from django.contrib.gis.db.models import MultiPolygonField
 from django.db import models
 
+from konova.enums import ServerMessageImportance
+
 
 class BaseResource(models.Model):
     """
@@ -69,3 +71,14 @@ class Geometry(BaseResource):
     """
     geom = MultiPolygonField(null=True, blank=True)
 
+
+class ServerMessage(BaseResource):
+    """
+    Holds messages, which can be displayed on the user's dashboard
+    """
+    subject = models.CharField(max_length=500, null=False, blank=False)
+    body = models.TextField()
+    is_active = models.BooleanField(default=True)
+    publish_on = models.DateTimeField()
+    unpublish_on = models.DateTimeField()
+    importance = models.CharField(max_length=100, choices=ServerMessageImportance.as_choices(drop_empty_choice=True))
diff --git a/konova/settings.py b/konova/settings.py
index a25f0cd7..5f47f5b8 100644
--- a/konova/settings.py
+++ b/konova/settings.py
@@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/3.1/ref/settings/
 from django.utils.translation import gettext_lazy as _
 
 # Load other settings
+from konova.enums import ServerMessageImportance
 from konova.sub_settings.django_settings import *
 
 # Num of days if user enables Remember-me on login
@@ -54,3 +55,10 @@ DEFAULT_ZOOM = 8.0
 DEFAULT_GROUP = _("Default")
 ZB_GROUP = _("Registration office")
 ETS_GROUP = _("Conservation office")
+
+# ServerMessageImportance bootstrap resolver
+SVI_BOOTSTRAP_CLS_MAP = {
+    ServerMessageImportance.DEFAULT.value: None,
+    ServerMessageImportance.WARNING.value: "alert-danger",
+    ServerMessageImportance.INFO.value: "alert-info",
+}
diff --git a/konova/static/css/konova.css b/konova/static/css/konova.css
index 95f35ccb..341d5e22 100644
--- a/konova/static/css/konova.css
+++ b/konova/static/css/konova.css
@@ -18,6 +18,10 @@ body{
     margin-bottom: 40px; /* Margin bottom by footer height */
 }
 
+.body-content{
+    margin: 1rem 0rem 0 0rem;
+}
+
 .footer {
     position: absolute;
     bottom: 0;
@@ -63,4 +67,18 @@ nav{
     Overwrites bootstrap default nav-link colouring
     */
     color: white;
+}
+
+.card{
+    margin: 0 0.5rem 0.5rem 0;
+    font-size: 12px;
+}
+.card:hover{
+    box-shadow: 1px 1px 3px var(--rlp-gray-light);
+}
+
+.card .card-text{
+    font-size: 12px;
+    max-height: 150px;
+    overflow: auto;
 }
\ No newline at end of file
diff --git a/konova/templates/konova/home.html b/konova/templates/konova/home.html
index ae7704ac..87b2554a 100644
--- a/konova/templates/konova/home.html
+++ b/konova/templates/konova/home.html
@@ -1,44 +1,38 @@
 {% extends 'base.html' %}
-{% load i18n %}
+{% load i18n ksp_filters %}
 
-{% block body_middle %}
-    <h1>Kompensationsverzeichnis</h1>
-    <h2>Service Portal</h2>
-    <hr>
-{% if user.is_anonymous %}
-    <a href="{% url 'simple-sso-login' %}">
-        <button class="button middle">
-            {% trans 'Proceed with login' %}
-        </button>
-    </a>
-{% else %}
-    <article>
-        {% trans 'Logged in as' %}  <strong>{{ user.username }}</strong>
-        <br>
-        {% trans 'Last login on' %} {{ user.last_login }}
-    </article>
-
-    <form action="{{form.action_url}}" method="post">
-        {% csrf_token %}
-        <table>
-            {% comment %}
-            This is an alternative to using the <article></article>
-            <tr>
-                <td>{% trans 'Logged in as' %}</td>
-                <td><strong>{{ user.username }}</strong></td>
-            </tr>
-            <tr>
-                <td>{% trans 'Last login on' %}</td>
-                <td><strong>{{ user.last_login }}</strong></td>
-            </tr>
-            {% endcomment %}
-            {% for field in form %}
-            <tr>
-                <td>{{ field.label }}</td>
-                <td>{{ field }}</td>
-            </tr>
+{% block body %}
+    <div id="server-messages" class="row px-3">
+        <h4 class="row">{% trans 'News' %}</h4>
+        <div class="row px-3">
+            {% for msg in msgs %}
+            <div class="card col-md {{msg.importance|bootstrap_cls}}">
+                <div class="card-body">
+                    <h6 class="card-title">{{msg.subject}}</h6>
+                    <small>{% trans 'Published on' %} {{msg.publish_on}}</small>
+                    <article class="card-text">{{msg.body|safe}}</article>
+                </div>
+            </div>
             {% endfor %}
-        </table>
-    </form>
-{% endif %}
+            <div class="card col-md {{msg.importance|bootstrap_cls}} align-items-center justify-content-center">
+                <a class="w-100 h-100 align-middle text-center" href="{% url 'home' %}">
+                    <div class="card-body">
+                        <h5 class="card-title">{% trans 'Older ...' %}</h5>
+                    </div>
+                </a>
+            </div>
+        </div>
+    </div>
+
+    <hr>
+
+    <div id="quickstart" class="col-md px-3">
+        <h4 class="row">{% trans 'Quickstart' %}</h4>
+        <div class="row px-3">
+            <div class="col-md">{% trans 'Intervention' %}</div>
+            <div class="col-md">{% trans 'Compensation' %}</div>
+            <div class="col-md">{% trans 'Eco-account' %}</div>
+        </div>
+    </div>
+
 {% endblock %}
\ No newline at end of file
diff --git a/konova/templatetags/__init__.py b/konova/templatetags/__init__.py
new file mode 100644
index 00000000..e6632d6a
--- /dev/null
+++ b/konova/templatetags/__init__.py
@@ -0,0 +1,7 @@
+"""
+Author: Michel Peltriaux
+Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
+Contact: michel.peltriaux@sgdnord.rlp.de
+Created on: 05.07.21
+
+"""
diff --git a/konova/templatetags/ksp_filters.py b/konova/templatetags/ksp_filters.py
new file mode 100644
index 00000000..6ee3dd34
--- /dev/null
+++ b/konova/templatetags/ksp_filters.py
@@ -0,0 +1,28 @@
+"""
+Author: Michel Peltriaux
+Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
+Contact: michel.peltriaux@sgdnord.rlp.de
+Created on: 05.07.21
+
+"""
+from django import template
+from konova.settings import SVI_BOOTSTRAP_CLS_MAP
+
+# Create custom library
+register = template.Library()
+
+
+@register.filter("bootstrap_cls")
+def bootstrap_cls(value):
+    """ Returns a bootstrap html class name
+
+    Resolves ServerMessageImportance enum into a html class name
+
+    Args:
+        value ():
+        arg ():
+
+    Returns:
+
+    """
+    return SVI_BOOTSTRAP_CLS_MAP.get(value, "")
diff --git a/konova/views.py b/konova/views.py
index 09030525..daaa447a 100644
--- a/konova/views.py
+++ b/konova/views.py
@@ -9,8 +9,10 @@ from django.contrib.auth import logout
 from django.contrib.auth.decorators import login_required
 from django.http import HttpRequest
 from django.shortcuts import redirect, render
+from django.utils import timezone
 
 from konova.contexts import BaseContext
+from konova.models import ServerMessage
 from konova.settings import SSO_SERVER_BASE
 
 
@@ -40,7 +42,18 @@ def home_view(request: HttpRequest):
         A redirect
     """
     template = "konova/home.html"
+    now = timezone.now()
+    # Fetch the four newest active and published ServerMessages
+    msgs = ServerMessage.objects.filter(
+        is_active=True,
+        publish_on__lte=now,
+        unpublish_on__gte=now,
+    ).order_by(
+        "-publish_on"
+    )[:4]
 
-    additional_context = {}
+    additional_context = {
+        "msgs": msgs,
+    }
     context = BaseContext(request, additional_context).context
     return render(request, template, context)
diff --git a/locale/de/LC_MESSAGES/django.mo b/locale/de/LC_MESSAGES/django.mo
index 4ed51b012db15f0c02dfacea54e67700f54a0238..847f6c43c080f54bef273736b5dc8241f2643b6f 100644
GIT binary patch
delta 1479
zcmYM!OGs2v9LMo9spDhRQY*_Ij%8(PTB&JDizKr}WM;Go3Lo7WhsImX+@XiXfVhaL
zMNCCfEuuw15rJ0NGF_#+f;JJjXc4^@<}RY|Z#>cA{_p3WGjq@RpU2E}*|)Ofr{c_8
zhSEl?C4Tvg>B89zZj_uXW3n+9i?Im(Sc&;qg9X@v`rdvl!9$pb{r2-ATtR&pbMXf9
ze$w3KAwa`p%)|*S!bwzzGq?udA(#2dZ7D9`R?H$By;pB-L=C(fmEb;Hj@_sPLa2l<
zrA-=hl?P4s4sw}$w*C-vs6Rpt@Z7e)K+Rwhm*Es@p!c?Y4wd*<+dgkqqY^7Xt<Wm;
zGrp<ify*>-Q-^J+0S}@Q=tj-_xNYyn&D0$%$7{F_pJFw>we<yTq+UWNwRixPcmmtm
z<|Hc28(LT64C)J?xoJi}u@HZwwkSaQ%DfcyUJdF@G-4TcBA4m64x#!xZ|ftd_phV+
ze~`!iYfqlhK(b~UwYRfaj~`Jp&u4V4NHOYrrKkkTQF~j3t8fo$z+<SydQtDkQQyB{
z>m$fzt^`<rb$pYW&cGPzaNI}D{0VAHUL%*8;idsTpk^?K8t8|u`)E|X5H(<hwHkG(
z8&L0epvLJ+@}LY)pb{8B{S3pXnT?|Mb_|>F6$bG;R$(E%=qxm&Iy}jZtxYGP@2lv2
z4N8t?2cfOfs_R#ks{>R@Y)Z{#lq9QpQqj;lI?aR@R-3Yws3mk#R5lRW&FzFXOVe0S
zsBBxrY(e`+l5T0?USU5ILHoQLnUR~WuH;^6Kd3=1Tr07Ws3TM~XMR_vfzU>26aSSZ
zJZKG7^tYxB)Y|Ce>>_p&T01j7ms#)2aH3~Zh5oSbT<V6uvnhJYi3RKG>P**J#|;i&
zHeIoBpBuT@=S9xA=5V4v8i@}&r-D?v6On<_aj!4trT+L^b9x-li@4$VcysndMrI@$
za#CON`m>HW1A|^F5jeVcH0n7qC*Aqf?NG>d{&yc=?EaV&n|c`vIj$Ft@K&&I$n*>h
cx=u8@ILv&YJ-;L3#ywgRZrB-b$S?B!1vQSGJ^%m!

delta 1441
zcmYk+TSyd99LMpqdD(QeH7|L|a<bg=l2%@_f-Xk%pkh=MSb~d<>z3`NJ7p-b^dLk8
zQCosV5Iuxt(8E4Ny;cxG1Vscr<V!_`5JJ&oeShmn9p=nu=IosL|IhjF?rhn!viQgR
z^y`MUg<eko<T0iTAEa@jeN8vUi{CIG=P(n~GmObWALe2S>bU?GU_EAIoBMeu7IA+B
zvv3HRA2(xM_!zi=yxUyEr8tRt;WRGCByyP7oc#C>tMM~xo}a7~un?741r}l*D)25;
zqK94WlyPHXTxhZ9Q4`0J!(4U8Cvh?Nw@`uZy5rNRl{~~ee2kj^5|#LS_kISobF-+O
z`GXv$fQP)qH)UMt1(m1(ji{Bjy7${L!2NElz~i_AFJcW&x%Y3eiTgRM!vI+;!2{Sv
zS$j|mxy@iH-ov;ac*;qczrrQ>0acQ3sEmK1CT6j}T1h^ZVHI+iov!W3qvnu%-;0`m
z0`>klsuY)y9L=3<>aSYfXP^O}pmyN9`@j!W;NPfPDytGGLItWvCDe*~aXV_~f~bXr
zQ1j2Y<8kCL<D3-dijVzQ?I#$}m*WO%;uNYRk5GYLpjPk(mB<V#@K00#FCWT0)R(su
zHLn(xP%|pdHq@_d2kJdX2e?ozhp-thqlM3L9ezR8-cNQ)u!R$)Oa*U5HN8;5$R*WO
zTkVEQWYL$=0|`%hL3|TeY6{&%SHxnvYEVsA)BdWhrmJ|WOFdo7SV>o_n<sVFvKCqk
z7nO9aNNv?TW;3#oNb0tRbCvr+Eo#47>1*ig>1u1~`i*R)s~#%WLR-Xz{t(pkucbO^
zYxIp$+d$XWRU|zb4W2}Erd=L$tifm~9I>Ji(-9mo9nnz8K4vixj3sVn?hTx>Bi7hC
z(={9lM#7^(C(MKUhNFEpPmP3~f%)l)V(->uw>O!VDDd^xbe|ryol(cK!;z59>qCwe
zJZbjZeFKi!^WWHDEOFL%ux6saKVtt25}Oaw8FnnPA(Q^-u+twL7`7vc+?=*#PmbU7
E7aZM{&j0`b

diff --git a/locale/de/LC_MESSAGES/django.po b/locale/de/LC_MESSAGES/django.po
index 9a1f6521..2ee96d0b 100644
--- a/locale/de/LC_MESSAGES/django.po
+++ b/locale/de/LC_MESSAGES/django.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-07-02 12:56+0200\n"
+"POT-Creation-Date: 2021-07-05 14:48+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -43,7 +43,8 @@ msgstr "Aktionen"
 msgid "Compensations"
 msgstr "Kompensationen"
 
-#: compensation/tables.py:48 compensation/tables.py:98 templates/navbar.html:22
+#: compensation/tables.py:48 compensation/tables.py:98
+#: konova/templates/konova/home.html:33 templates/navbar.html:26
 msgid "Compensation"
 msgstr "Kompensation"
 
@@ -139,7 +140,8 @@ msgid "Interventions"
 msgstr "Eingriffe"
 
 #: intervention/tables.py:57 intervention/tables.py:68
-#: intervention/templates/intervention/open.html:8 templates/navbar.html:16
+#: intervention/templates/intervention/open.html:8
+#: konova/templates/konova/home.html:32 templates/navbar.html:20
 msgid "Intervention"
 msgstr "Eingriff"
 
@@ -183,29 +185,49 @@ msgstr "Entferne"
 msgid "You are about to remove {} {}"
 msgstr "Sie sind dabei {} {} zu löschen"
 
-#: konova/settings.py:54
+#: konova/settings.py:55
 msgid "Default"
 msgstr ""
 
-#: konova/settings.py:55
+#: konova/settings.py:56
 msgid "Registration office"
 msgstr "Zulassungsbehörde"
 
-#: konova/settings.py:56
+#: konova/settings.py:57
 msgid "Conservation office"
 msgstr "Naturschutzbehörde"
 
-#: konova/templates/konova/home.html:11
-msgid "Proceed with login"
-msgstr "Mit Login fortfahren"
+#: konova/templates/konova/home.html:6
+msgid "News"
+msgstr ""
 
-#: konova/templates/konova/home.html:16
-msgid "Logged in as"
-msgstr "Eingeloggt als"
+#: konova/templates/konova/home.html:12
+msgid "Published on"
+msgstr "Veröffentlicht am"
 
-#: konova/templates/konova/home.html:18
-msgid "Last login on"
-msgstr "Zuletzt eingeloggt am"
+#: konova/templates/konova/home.html:20
+msgid "Older ..."
+msgstr "Ältere ..."
+
+#: konova/templates/konova/home.html:30
+msgid "Quickstart"
+msgstr "Schnellstart"
+
+#: konova/templates/konova/home.html:34 templates/navbar.html:32
+msgid "Eco-account"
+msgstr "Ökokonto"
+
+#: templates/footer.html:6
+msgid "Help"
+msgstr "Hilfe"
+
+#: templates/footer.html:9
+msgid "Impressum"
+msgstr ""
+
+#: templates/footer.html:12
+msgid "Contact"
+msgstr ""
 
 #: templates/generic_table_form.html:37
 msgid "Fields with * are required."
@@ -227,35 +249,35 @@ msgstr ""
 msgid "KSP"
 msgstr ""
 
-#: templates/navbar.html:10
+#: templates/navbar.html:14
 msgid "Home"
 msgstr "Home"
 
-#: templates/navbar.html:28
-msgid "Eco-account"
-msgstr "Ökokonto"
-
-#: templates/navbar.html:34
+#: templates/navbar.html:38
 msgid "More"
 msgstr "Mehr"
 
-#: templates/navbar.html:37
+#: templates/navbar.html:41
 msgid "EMA"
 msgstr ""
 
-#: templates/navbar.html:38
+#: templates/navbar.html:42
 msgid "Import..."
 msgstr ""
 
-#: templates/navbar.html:39
+#: templates/navbar.html:43
 msgid "Export..."
 msgstr ""
 
-#: templates/navbar.html:40
+#: templates/navbar.html:44
 msgid "Reports"
 msgstr "Berichte"
 
-#: templates/navbar.html:51
+#: templates/navbar.html:56
+msgid "Settings"
+msgstr "Einstellungen"
+
+#: templates/navbar.html:57
 msgid "Logout"
 msgstr "Abmelden"
 
@@ -1466,6 +1488,15 @@ msgstr ""
 msgid "A fontawesome icon field"
 msgstr ""
 
+#~ msgid "Proceed with login"
+#~ msgstr "Mit Login fortfahren"
+
+#~ msgid "Logged in as"
+#~ msgstr "Eingeloggt als"
+
+#~ msgid "Last login on"
+#~ msgstr "Zuletzt eingeloggt am"
+
 #~ msgid "Add new intervention"
 #~ msgstr "Neuen Eingriff hinzufügen"
 
@@ -1559,12 +1590,6 @@ msgstr ""
 #~ msgid "Annual report"
 #~ msgstr "Jahresbericht"
 
-#~ msgid "Settings"
-#~ msgstr "Einstellungen"
-
-#~ msgid "Help"
-#~ msgstr "Hilfe"
-
 #~ msgid "User"
 #~ msgstr "Nutzer"
 
diff --git a/templates/base.html b/templates/base.html
index 8eadff81..38506216 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -18,8 +18,10 @@
             {% include 'navbar.html' %}
         {% endblock %}
     </header>
-    <div class="container-fluid">
+    <div class="container-fluid mt-3 px-5">
+        {% block body %}
 
+        {% endblock %}
     </div>
 
     {% block footer %}