diff --git a/src/open_inwoner/configurations/admin.py b/src/open_inwoner/configurations/admin.py index b41796c9ce..8ec9f0096b 100644 --- a/src/open_inwoner/configurations/admin.py +++ b/src/open_inwoner/configurations/admin.py @@ -274,6 +274,15 @@ class SiteConfigurationAdmin(OrderedInlineModelAdminMixin, SingletonModelAdmin): ), }, ), + ( + _("Customer satisfaction survey"), + { + "fields": ( + "kcm_survey_link_text", + "kcm_survey_link_url", + ), + }, + ), ( _("Display options for anonymous users"), { diff --git a/src/open_inwoner/configurations/migrations/0065_siteconfiguration_kcm_survey_link_text_and_more.py b/src/open_inwoner/configurations/migrations/0065_siteconfiguration_kcm_survey_link_text_and_more.py new file mode 100644 index 0000000000..351f312329 --- /dev/null +++ b/src/open_inwoner/configurations/migrations/0065_siteconfiguration_kcm_survey_link_text_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 4.2.11 on 2024-04-02 13:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("configurations", "0064_auto_20240304_1200"), + ] + + operations = [ + migrations.AddField( + model_name="siteconfiguration", + name="kcm_survey_link_text", + field=models.CharField( + blank=True, + help_text="The text that is displayed on the customer satisfaction survey link", + max_length=255, + verbose_name="KCM survey link text", + ), + ), + migrations.AddField( + model_name="siteconfiguration", + name="kcm_survey_link_url", + field=models.URLField( + blank=True, + help_text="The external link for the customer satisfaction survey.", + verbose_name="KCM survey URL", + ), + ), + ] diff --git a/src/open_inwoner/configurations/models.py b/src/open_inwoner/configurations/models.py index 7669e6c934..75966104e5 100644 --- a/src/open_inwoner/configurations/models.py +++ b/src/open_inwoner/configurations/models.py @@ -452,6 +452,19 @@ class SiteConfiguration(SingletonModel): verbose_name=_("Privacy page link"), help_text=_("The link to the cookie policy page."), ) + kcm_survey_link_text = models.CharField( + max_length=255, + blank=True, + verbose_name=_("KCM survey link text"), + help_text=_( + "The text that is displayed on the customer satisfaction survey link" + ), + ) + kcm_survey_link_url = models.URLField( + verbose_name=_("KCM survey URL"), + blank=True, + help_text=_("The external link for the customer satisfaction survey."), + ) openid_connect_logo = FilerImageField( verbose_name=_("Openid Connect Logo"), null=True, diff --git a/src/open_inwoner/configurations/tests/test_kcm_survey.py b/src/open_inwoner/configurations/tests/test_kcm_survey.py new file mode 100644 index 0000000000..ca91e4c872 --- /dev/null +++ b/src/open_inwoner/configurations/tests/test_kcm_survey.py @@ -0,0 +1,51 @@ +from unittest.mock import patch + +from django.test import TestCase + +from pyquery import PyQuery as PQ + +from open_inwoner.cms.profile.cms_apps import ProfileApphook +from open_inwoner.cms.tests import cms_tools +from open_inwoner.configurations.models import SiteConfiguration + + +class KCMSurveyTestCase(TestCase): + css_selector = ".kcm-survey" + + def setUp(self): + cms_tools.create_apphook_page(ProfileApphook) + + @patch( + "open_inwoner.configurations.models.SiteConfiguration.get_solo", + return_value=SiteConfiguration( + kcm_survey_link_text="Geef je mening", + kcm_survey_link_url="https://some-kcm-survey.url/foo", + ), + ) + def test_kcm_survey_configured(self, mock_config): + response = self.client.get("/") + + doc = PQ(response.content) + + self.assertEqual(len(doc.find(self.css_selector)), 1) + + def test_kcm_survey_not_configured(self): + invalid_configs = ( + ("Geef je mening", ""), + ("", "https://some-kcm-survey.url/foo"), + ("", ""), + ) + for text, url in invalid_configs: + with self.subTest(text=text, url=url): + + with patch( + "open_inwoner.configurations.models.SiteConfiguration.get_solo", + return_value=SiteConfiguration( + kcm_survey_link_text=text, kcm_survey_link_url=url + ), + ): + response = self.client.get("/") + + doc = PQ(response.content) + + self.assertEqual(len(doc.find(self.css_selector)), 0) diff --git a/src/open_inwoner/scss/components/KCMSurvey/KCMSurvey.scss b/src/open_inwoner/scss/components/KCMSurvey/KCMSurvey.scss new file mode 100644 index 0000000000..76d0840b27 --- /dev/null +++ b/src/open_inwoner/scss/components/KCMSurvey/KCMSurvey.scss @@ -0,0 +1,15 @@ +.kcm-survey { + position: fixed; + inset: 50% -20px auto auto; + transform: rotate(180deg) translateX(50%) translateY(50%); + writing-mode: vertical-rl; + z-index: 1010; + padding: var(--spacing-medium); + background-color: var(--color-info-lighter); + font-size: var(--font-size-heading-card); + font-weight: bold; + + & .link { + color: var(--color-info-darker); + } +} diff --git a/src/open_inwoner/scss/components/_index.scss b/src/open_inwoner/scss/components/_index.scss index 9e52b8f27c..810a1cb588 100644 --- a/src/open_inwoner/scss/components/_index.scss +++ b/src/open_inwoner/scss/components/_index.scss @@ -55,6 +55,7 @@ @import './Hero/Hero.scss'; @import './Icon/Icon.scss'; @import './Image/Image.scss'; +@import './KCMSurvey/KCMSurvey.scss'; @import './List/List.scss'; @import './List/ListItem.scss'; @import './Logo/DigidLogo.scss'; diff --git a/src/open_inwoner/templates/master.html b/src/open_inwoner/templates/master.html index 184a617459..20fff6504e 100644 --- a/src/open_inwoner/templates/master.html +++ b/src/open_inwoner/templates/master.html @@ -1,4 +1,4 @@ -{% load static i18n card_tags button_tags link_tags notification_tags anchor_menu_tags view_breadcrumbs utils session_tags django_htmx cms_tags menu_tags sekizai_tags %} +{% load static i18n card_tags button_tags link_tags notification_tags anchor_menu_tags view_breadcrumbs utils solo_tags session_tags django_htmx cms_tags menu_tags sekizai_tags %} @@ -136,6 +136,13 @@ {% endblock main_outer %} + {% get_solo 'configurations.SiteConfiguration' as config %} + {% if config.kcm_survey_link_url and config.kcm_survey_link_text %} +
+ {% link bold=True href=config.kcm_survey_link_url text=config.kcm_survey_link_text blank=True hide_external_icon=True %} +
+ {% endif %} + {% if footer %}