From a0daf4b0a5309ca21ea5a3f692cddf6af0f528de Mon Sep 17 00:00:00 2001 From: Jiro Ghianni Date: Thu, 25 Jan 2024 14:49:02 +0100 Subject: [PATCH 1/5] [#2036] Added tab navigation for login pages --- src/eherkenning/tests/test_mock_views.py | 4 +- .../registration_form.html | 5 +- .../templates/registration/login.html | 206 ++++++++------- .../registration/login_business.html | 64 +++++ .../templates/registration/login_email.html | 41 +++ src/open_inwoner/accounts/tests/test_auth.py | 8 +- .../accounts/tests/test_auth_2fa_sms.py | 25 +- src/open_inwoner/accounts/views/__init__.py | 2 + src/open_inwoner/accounts/views/login.py | 8 + .../templates/components/Header/Header.html | 2 +- .../Header/NavigationAuthenticated.html | 2 +- .../scss/components/Button/Button.scss | 13 + .../scss/components/Card/Card.scss | 20 +- .../scss/components/TabPanel/TabPanel.scss | 236 ++++++++++++------ .../scss/components/Typography/Link.scss | 11 + src/open_inwoner/urls.py | 13 +- 16 files changed, 457 insertions(+), 203 deletions(-) create mode 100644 src/open_inwoner/accounts/templates/registration/login_business.html create mode 100644 src/open_inwoner/accounts/templates/registration/login_email.html diff --git a/src/eherkenning/tests/test_mock_views.py b/src/eherkenning/tests/test_mock_views.py index 00778fc6dc..3288f4673d 100644 --- a/src/eherkenning/tests/test_mock_views.py +++ b/src/eherkenning/tests/test_mock_views.py @@ -45,7 +45,7 @@ class TestAppIndexTests(TestCase): def test_eherkenning_enabled(self, mock_solo): mock_solo.return_value.eherkenning_enabled = True - url = reverse("login") + url = reverse("login_business") response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -54,7 +54,7 @@ def test_eherkenning_enabled(self, mock_solo): def test_eherkenning_disabled(self, mock_solo): mock_solo.return_value.eherkenning_enabled = False - url = reverse("login") + url = reverse("login_business") response = self.client.get(url) self.assertEqual(response.status_code, 200) diff --git a/src/open_inwoner/accounts/templates/django_registration/registration_form.html b/src/open_inwoner/accounts/templates/django_registration/registration_form.html index 7f206a1caa..7c62d9a047 100644 --- a/src/open_inwoner/accounts/templates/django_registration/registration_form.html +++ b/src/open_inwoner/accounts/templates/django_registration/registration_form.html @@ -3,7 +3,7 @@ {% block content %} -
+

{% trans 'Registreren' %}

{% render_grid %} {% if settings.DIGID_ENABLED and digid_url %} {% render_column start=5 span=5 %} @@ -30,13 +30,12 @@ {% if login_allow_registration %} {% render_column start=5 span=5 %} {% render_card tinted=True compact=True %} -

{% trans "Registreren met E-mail" %}


+

{% trans "Registreren met E-mail" %}

{% form form_object=form method="POST" id="registration-form" submit_text=_('Registreren') extra_classes="form__registration" show_required=True %} {% endrender_card %} {% endrender_column %} {% endif %} {% endrender_grid %} -
{% endblock content %} diff --git a/src/open_inwoner/accounts/templates/registration/login.html b/src/open_inwoner/accounts/templates/registration/login.html index 5a11e3abcd..52d58a9490 100644 --- a/src/open_inwoner/accounts/templates/registration/login.html +++ b/src/open_inwoner/accounts/templates/registration/login.html @@ -1,5 +1,5 @@ {% extends 'master.html' %} -{% load i18n static utils grid_tags card_tags form_tags link_tags button_tags solo_tags cms_tags %} +{% load i18n static utils grid_tags card_tags form_tags link_tags button_tags icon_tags solo_tags cms_tags %} {% block header_image %} @@ -8,95 +8,125 @@ {% block content %} -
- {% render_grid %} - {% render_column start=5 span=5 %} - {% render_card %} -

{% trans 'Welkom' %}

- {% if login_text %}
{{ login_text|markdown|safe }}
{% endif %} -
- {% if settings.DIGID_ENABLED %} - {% get_solo 'digid_eherkenning_oidc_generics.OpenIDConnectDigiDConfig' as digid_oidc_config %} - {% if digid_oidc_config.enabled %} - {% render_card direction='horizontal' tinted=True compact=True %} - - {% url 'digid_oidc:init' as href %} - {% with href|addnexturl:next as href_with_next %} - {% link href=href_with_next text=_('Inloggen met DigiD') secondary=True icon='arrow_forward' extra_classes="link--digid" %} - {% endwith %} - {% endrender_card %} - {% else %} - {% render_card direction='horizontal' tinted=True compact=True %} - - {% url 'digid:login' as href %} - {% with href|addnexturl:next as href_with_next %} - {% link href=href_with_next text=_('Inloggen met DigiD') secondary=True icon='arrow_forward' extra_classes="link--digid" %} - {% endwith %} - {% endrender_card %} - {% endif %} - {% endif %} +

{% trans 'Welkom' %}

+ {% if login_text %} +
{{ login_text|markdown|safe }}
+ {% endif %} - {% if eherkenning_enabled %} - {% get_solo 'digid_eherkenning_oidc_generics.OpenIDConnectEHerkenningConfig' as eherkenning_oidc_config %} - {% if eherkenning_oidc_config.enabled %} - {% render_card direction='horizontal' tinted=True compact=True %} - - {% url 'eherkenning_oidc:init' as href %} - {% with href|addnexturl:next as href_with_next %} - {% link href=href_with_next text=_('Inloggen met eHerkenning') secondary=True icon='arrow_forward' extra_classes="link--eherkenning" %} - {% endwith %} - {% endrender_card %} - {% else %} - {% render_card direction='horizontal' tinted=True compact=True %} - - {% url 'eherkenning:login' as href %} - {% with href|addnexturl:next as href_with_next %} - {% link href=href_with_next text=_('Inloggen met eHerkenning') secondary=True icon='arrow_forward' extra_classes="link--eherkenning" %} - {% endwith %} - {% endrender_card %} - {% endif %} - {% endif %} + {# Tab panels Start #} + + {# Tab panels End #} {% endblock content %} diff --git a/src/open_inwoner/accounts/templates/registration/login_business.html b/src/open_inwoner/accounts/templates/registration/login_business.html new file mode 100644 index 0000000000..5b639400bc --- /dev/null +++ b/src/open_inwoner/accounts/templates/registration/login_business.html @@ -0,0 +1,64 @@ +{% extends 'master.html' %} +{% load i18n static utils grid_tags card_tags form_tags link_tags button_tags icon_tags solo_tags cms_tags %} + + +{% block header_image %} + {% static_placeholder 'login_banner' %} +{% endblock header_image %} + + +{% block content %} + +

{% trans 'Inloggen' %}

+ {% if login_text %} +
{{ login_text|markdown|safe }}
+ {% endif %} + + {# Tab panels Start #} + + {# Tab panels End #} + +{% endblock content %} diff --git a/src/open_inwoner/accounts/templates/registration/login_email.html b/src/open_inwoner/accounts/templates/registration/login_email.html new file mode 100644 index 0000000000..56d513148d --- /dev/null +++ b/src/open_inwoner/accounts/templates/registration/login_email.html @@ -0,0 +1,41 @@ +{% extends 'master.html' %} +{% load i18n static form_tags card_tags link_tags grid_tags button_tags icon_tags %} + +{% block content %} + +

{% trans 'Log in met e-mail adres' %}

+ + {# Tab panels Start #} + + {# Tab panels End #} + +{% endblock content %} diff --git a/src/open_inwoner/accounts/tests/test_auth.py b/src/open_inwoner/accounts/tests/test_auth.py index 2bc07869ad..67dcc6f6c5 100644 --- a/src/open_inwoner/accounts/tests/test_auth.py +++ b/src/open_inwoner/accounts/tests/test_auth.py @@ -1660,7 +1660,7 @@ def test_login_page_has_next_url(self): def test_login(self): """Test that a user is successfully logged in.""" - form = self.app.get(reverse("login")).forms["login-form"] + form = self.app.get(reverse("login_email")).forms["login-form"] form["username"] = self.user.email form["password"] = "test" form.submit().follow() @@ -1706,7 +1706,7 @@ def test_login_page_shows_correct_eherkenning_login_url(self): else f"{reverse('eherkenning:login')}?next=" ) - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_business")) eherkenning_login_title = _("Inloggen met eHerkenning") eherkenning_login_link = response.pyquery( @@ -1720,7 +1720,7 @@ def test_login_for_inactive_user_shows_appropriate_message(self): self.user.is_active = False self.user.save() - form = self.app.get(reverse("login")).forms["login-form"] + form = self.app.get(reverse("login_email")).forms["login-form"] form["username"] = self.user.email form["password"] = "test" response = form.submit() @@ -1735,7 +1735,7 @@ def test_login_for_inactive_user_shows_appropriate_message(self): ) def test_login_with_wrong_credentials_shows_appropriate_message(self): - form = self.app.get(reverse("login")).forms["login-form"] + form = self.app.get(reverse("login_email")).forms["login-form"] form["username"] = self.user.email form["password"] = "wrong_password" response = form.submit() diff --git a/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py b/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py index 2fd7ec827b..473cc87989 100644 --- a/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py +++ b/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py @@ -39,7 +39,7 @@ def test_regular_login_with_2fa_disabled(self, mock_gateway_send): self.config.login_2fa_sms = False self.config.save() - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -54,7 +54,7 @@ def test_regular_login_with_2fa_disabled(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_with_valid_token_succeeds(self, mock_gateway_send): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -76,7 +76,7 @@ def test_login_with_valid_token_succeeds(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_with_invalid_token_fails(self, mock_gateway_send): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -101,7 +101,7 @@ def test_login_with_invalid_token_fails(self, mock_gateway_send): def test_login_fails_with_sms_failure(self, mock_gateway_send): mock_gateway_send.side_effect = GatewayError - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -138,7 +138,7 @@ def test_login_fails_with_sms_failure(self, mock_gateway_send): @override_settings(ACCOUNTS_USER_TOKEN_EXPIRE_TIME=300) def test_login_fails_with_token_timeout(self, mock_gateway_send): with freeze_time("2023-05-22 11:00:00"): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -160,11 +160,12 @@ def test_login_fails_with_token_timeout(self, mock_gateway_send): response = verify_token_form.submit() self.assertRedirects(response, reverse("login")) + # Or to view reverse("login") ? @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_token_with_max_attempts(self, mock_gateway_send): with freeze_time("2023-05-22 12:00:00") as frozen_time: - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() # login form @@ -204,7 +205,7 @@ def test_login_token_with_max_attempts(self, mock_gateway_send): frozen_time.tick(delta=datetime.timedelta(minutes=-1)) other_user = UserFactory(email="ex2@example.com", password="secret2") - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) login_form = response.forms["login-form"] login_form["username"] = other_user.email login_form["password"] = "secret2" @@ -229,7 +230,7 @@ def test_login_token_with_max_attempts(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") @freeze_time("2023-05-22 12:00:00") def test_login_when_resending_sms(self, mock_gateway_send): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -275,7 +276,7 @@ def test_login_resend_sms_max_attempts( self, mock_gateway_send, mock_login_throttle_visits ): with freeze_time("2023-05-22 12:00:00"): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -325,7 +326,7 @@ def test_login_resend_sms_max_attempts( # new attempt 5 minutes later with freeze_time("2023-05-22 12:05:01"): - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) login_form = response.forms["login-form"] login_form["username"] = self.user.email login_form["password"] = "secret" @@ -386,7 +387,7 @@ def test_login_by_adding_phone_number_succeeds(self, mock_gateway_send): self.user.phonenumber = "" self.user.save() - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() form = response.forms["login-form"] @@ -424,7 +425,7 @@ def test_login_fails_with_different_phonenumbers(self, mock_gateway_send): self.user.phonenumber = "" self.user.save() - response = self.app.get(reverse("login")) + response = self.app.get(reverse("login_email")) mock_gateway_send.assert_not_called() form = response.forms["login-form"] diff --git a/src/open_inwoner/accounts/views/__init__.py b/src/open_inwoner/accounts/views/__init__.py index 8517315ec7..3f119e4ded 100644 --- a/src/open_inwoner/accounts/views/__init__.py +++ b/src/open_inwoner/accounts/views/__init__.py @@ -30,6 +30,7 @@ from .invite import InviteAcceptView from .login import ( AddPhoneNumberWizardView, + CustomBusinessLoginView, CustomLoginView, ResendTokenView, VerifyTokenView, @@ -71,6 +72,7 @@ "InviteAcceptView", "AddPhoneNumberWizardView", "CustomLoginView", + "CustomBusinessLoginView", "ResendTokenView", "VerifyTokenView", "PasswordResetView", diff --git a/src/open_inwoner/accounts/views/login.py b/src/open_inwoner/accounts/views/login.py index f2e52eea93..d001396835 100644 --- a/src/open_inwoner/accounts/views/login.py +++ b/src/open_inwoner/accounts/views/login.py @@ -91,6 +91,14 @@ def form_valid(self, form): return redirect(furl(reverse("verify_token")).add(params).url) +class CustomEmailLoginView(CustomLoginView): + template_name = "registration/login_email.html" + + +class CustomBusinessLoginView(CustomLoginView): + template_name = "registration/login_business.html" + + class VerifyTokenView(ThrottleMixin, FormView): throttle_visits = 3 throttle_period = 60 diff --git a/src/open_inwoner/components/templates/components/Header/Header.html b/src/open_inwoner/components/templates/components/Header/Header.html index 67f85e35a1..450a9541c7 100644 --- a/src/open_inwoner/components/templates/components/Header/Header.html +++ b/src/open_inwoner/components/templates/components/Header/Header.html @@ -24,7 +24,7 @@ {% endif %}
diff --git a/src/open_inwoner/components/templates/components/Header/NavigationAuthenticated.html b/src/open_inwoner/components/templates/components/Header/NavigationAuthenticated.html index 5e93437bbc..eccacad48e 100644 --- a/src/open_inwoner/components/templates/components/Header/NavigationAuthenticated.html +++ b/src/open_inwoner/components/templates/components/Header/NavigationAuthenticated.html @@ -36,7 +36,7 @@ {% url 'login' as login_url %} {% trans "Inloggen" as login %} - {% button text="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True transparent=True %} + {% button text="Inloggen" href=login_url icon="person" icon_position="before" primary=True icon_outlined=True %} {% endif %} diff --git a/src/open_inwoner/scss/components/Button/Button.scss b/src/open_inwoner/scss/components/Button/Button.scss index e5b76b2875..8f8dd96479 100644 --- a/src/open_inwoner/scss/components/Button/Button.scss +++ b/src/open_inwoner/scss/components/Button/Button.scss @@ -100,6 +100,19 @@ border-color: transparent; color: var(--color-primary); + &.button--primary { + border-color: transparent; + color: var(--color-primary); + background-color: transparent; + + &:hover { + background-color: transparent; + border-color: transparent; + color: var(--color-primary); + text-decoration: underline; + } + } + &.button--secondary { color: var(--color-secondary); background-color: transparent; diff --git a/src/open_inwoner/scss/components/Card/Card.scss b/src/open_inwoner/scss/components/Card/Card.scss index 11dcbe8aa2..542f1e109b 100644 --- a/src/open_inwoner/scss/components/Card/Card.scss +++ b/src/open_inwoner/scss/components/Card/Card.scss @@ -115,15 +115,22 @@ &--tinted { --card-color-background: var(--color-gray-lightest); + border: var(--card-size-border) solid var(--color-gray-lightest); // contrast for accessibility .form .caption__content { color: var(--color-tinted-mute); } - .card__body--direction-horizontal .link .link__text { - text-align: right; - padding-left: var(--spacing-small); + .card__body--direction-horizontal { + display: flex; + justify-content: space-between; + padding: 20px; + + .link .link__text { + text-align: right; + padding-left: var(--spacing-small); + } } } @@ -264,11 +271,6 @@ } } - &__body--direction-horizontal { - display: flex; - justify-content: space-between; - } - &__body--flex { display: flex; flex-direction: column; @@ -356,7 +358,7 @@ } /// On a stretched card, the one and only link after a list should be placed on above the bottom border. - &-- stretch &__body { + &--stretch &__body { padding-bottom: var(--card-spacing); @media (min-width: 768px) { diff --git a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss index 883f480431..c9c4c72111 100644 --- a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss +++ b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss @@ -4,118 +4,190 @@ display: flex; max-width: 100%; width: 100%; -} -.tabs { - background: #fff; - overflow: initial; - width: 100%; + .tabs { + background: #fff; + overflow: initial; + width: 100%; - @media (min-width: 500px) { - overflow: hidden; + @media (min-width: 500px) { + overflow: hidden; + } } -} - -.list.tabs__headers { - display: block; - align-items: center; - box-sizing: border-box; - width: 100%; - margin: 0; - overflow: hidden; - padding: 0; - position: relative; - &::before { - left: 0; - right: 0; - bottom: 0px; - height: 0; - border-bottom: 2px solid var(--color-gray-light); - content: ''; - top: auto; + .list.tabs__headers { display: block; - position: absolute; + align-items: center; + box-sizing: border-box; + width: 100%; + margin: 0; + overflow: hidden; + padding: 0; + position: relative; + + &::before { + left: 0; + right: 0; + bottom: 0px; + height: 0; + border-bottom: 2px solid var(--color-gray-light); + content: ''; + top: auto; + display: block; + position: absolute; + } + + &::after { + clear: both; + display: block; + content: ''; + } } - &::after { - clear: both; + .list-item.tab__header--item { + max-width: var(--mobile-xs-width); + border: none; display: block; - content: ''; + float: none; + padding: 0; + border: 0; + margin-right: -1px; + position: relative; + + @media (min-width: 360px) { + max-width: 200px; + float: left; + } } -} -.list-item.tab__header--item { - max-width: var(--mobile-xs-width); - border: none; - display: block; - float: none; - padding: 0; - border: 0; - margin-right: -1px; - position: relative; + .link.tab__header { + box-sizing: border-box; + color: var(--color-gray-lighter); + display: inline-block; + cursor: pointer; + width: 100%; + padding: var(--spacing-large); + transition: 0.3s; + + &:target { + scroll-margin-top: 150px; + } + &:target::before { + scroll-margin-top: 150px; + } - @media (min-width: 360px) { - max-width: 200px; - float: left; - } -} + &:active { + background-color: var(--color-white); + } -.link.tab__header { - box-sizing: border-box; - color: var(--color-gray-lighter); - display: inline-block; - cursor: pointer; - width: 100%; - padding: var(--spacing-large); - transition: 0.3s; + &.active { + border-bottom: 2px solid var(--color-primary); + color: var(--font-color-body); + font-weight: bold; + margin: 0; + } + } - &:target { + .tab__content, + .tab__content.active { + margin: 1em; scroll-margin-top: 150px; + + p { + padding: 0; + } } - &:target::before { - scroll-margin-top: 150px; + + .active { + display: block; } - &.active { - border-bottom: 2px solid var(--color-primary); - color: var(--font-color-body); - font-weight: bold; - margin: 0; + .hide { + display: none; } -} -.tabs__body { - padding: 0; + .tabs__body { + padding: 0; + + // Styling for Benefits reports/Mijn uitkeringen + .form { + //max-width: var(--mobile-ms-width); - // Styling for Benefits reports/Mijn uitkeringen - .form { - max-width: var(--mobile-ms-width); + .form__actions { + margin-top: 0; + } - .form__actions { - margin-top: 0; + .form__control [class*='icon'] { + transform: none; + } } + } - .form__control [class*='icon'] { - transform: none; + .form { + /// Make required asterisk visible for this component + .label__label--required { + color: var(--color-red); + padding-left: var(--spacing-tiny); + //make asterisks invisible by default, only make them visible if component has the caption + display: inline; } } } -.tab__content, -.tab__content.active { - margin: 1em; - scroll-margin-top: 150px; +/// Tabs on login page - p { - padding: 0; +.login-tab--container { + .list-item.tab__header--item { + min-width: 100px; + + @media (min-width: 500px) { + min-width: 180px; + } + } + + .link.tab__header { + font-weight: normal; + padding: var(--spacing-large) var(--spacing-large) var(--spacing-large) 0; + border-bottom: 2px solid var(--color-gray-light); + + // for inactive tabs + @media (min-width: 500px) { + border-bottom: none; + } + + &:active { + background-color: var(--color-white); + } + + &.active { + background-color: var(--color-white); + border-bottom: 2px solid var(--color-accent); + color: var(--color-accent); + font-weight: bold; + margin: 0; + } } -} -.active { - display: block; + .tab__content { + margin: var(--row-height) 0 0 0; + scroll-margin-top: 150px; + + .tab__heading-4 { + font-size: var(--font-size-heading-4); + margin-bottom: var(--spacing-large); + } + + .card { + & .link--next [class*='icon'] { + font-size: var(--font-size-body); + } + } + } } -.hide { - display: none; +/// Tabs voor login pages +.login-tab--container { + .tab-column__paragraph { + color: var(--color-gray-dark-900); + } } diff --git a/src/open_inwoner/scss/components/Typography/Link.scss b/src/open_inwoner/scss/components/Typography/Link.scss index 14eee75787..5de5e6f747 100644 --- a/src/open_inwoner/scss/components/Typography/Link.scss +++ b/src/open_inwoner/scss/components/Typography/Link.scss @@ -78,6 +78,17 @@ text-decoration: none; } + &.icon--large { + &:hover { + text-decoration: none; + } + + *[class*='icon'] { + color: var(--color-gray-90); + font-size: 46px; + } + } + *[class*='icon']:first-child, *[class*='Icon']:first-child { transform: scale(1); diff --git a/src/open_inwoner/urls.py b/src/open_inwoner/urls.py index 2e7b3c0ce6..c3084a342d 100644 --- a/src/open_inwoner/urls.py +++ b/src/open_inwoner/urls.py @@ -15,6 +15,7 @@ from open_inwoner.accounts.forms import CustomRegistrationForm from open_inwoner.accounts.views import ( AddPhoneNumberWizardView, + CustomBusinessLoginView, CustomDigiDAssertionConsumerServiceMockView, CustomDigiDAssertionConsumerServiceView, CustomeHerkenningAssertionConsumerServiceMockView, @@ -28,6 +29,7 @@ ResendTokenView, VerifyTokenView, ) +from open_inwoner.accounts.views.login import CustomEmailLoginView from open_inwoner.openklant.views.contactform import ContactFormView from open_inwoner.pdc.views import FAQView @@ -88,6 +90,16 @@ name="password_reset_confirm", ), path("accounts/login/", CustomLoginView.as_view(), name="login"), + path( + "accounts/login-email/", + CustomEmailLoginView.as_view(), + name="login_email", + ), + path( + "accounts/login-business/", + CustomBusinessLoginView.as_view(), + name="login_business", + ), path("accounts/verify/", VerifyTokenView.as_view(), name="verify_token"), path("accounts/resend-token/", ResendTokenView.as_view(), name="resend_token"), path( @@ -182,7 +194,6 @@ path("eherkenning/idp/", include("eherkenning.mock.idp.eherkenning_urls")), ] + urlpatterns - if settings.DEBUG: urlpatterns = [ # provide default styling template From ad225a44699471076f78922e1752b851cb3e9213 Mon Sep 17 00:00:00 2001 From: Jiro Ghianni Date: Thu, 4 Apr 2024 11:12:48 +0200 Subject: [PATCH 2/5] [#2036] Added single-page tab script and hash-navigation --- src/eherkenning/tests/test_mock_views.py | 4 +- .../registration_form.html | 4 +- .../templates/registration/login.html | 86 ++++++++++++------- .../registration/login_business.html | 64 -------------- .../templates/registration/login_email.html | 41 --------- src/open_inwoner/accounts/tests/test_auth.py | 8 +- .../accounts/tests/test_auth_2fa_sms.py | 25 +++--- src/open_inwoner/accounts/views/__init__.py | 2 - src/open_inwoner/accounts/views/login.py | 8 -- .../js/components/form/LoginForm.js | 83 ++++++++++++++++++ src/open_inwoner/js/components/form/index.js | 1 + src/open_inwoner/js/components/index.js | 3 + .../js/components/tab-panels/index.js | 72 ++++++++++++++++ .../scss/components/LoginForm/LoginForm.scss | 7 ++ .../scss/components/TabPanel/TabPanel.scss | 36 ++++++-- src/open_inwoner/scss/components/_index.scss | 1 + src/open_inwoner/scss/views/_view.scss | 9 ++ .../registration/password_reset_form.html | 25 +++--- src/open_inwoner/urls.py | 13 +-- 19 files changed, 296 insertions(+), 196 deletions(-) delete mode 100644 src/open_inwoner/accounts/templates/registration/login_business.html delete mode 100644 src/open_inwoner/accounts/templates/registration/login_email.html create mode 100644 src/open_inwoner/js/components/form/LoginForm.js create mode 100644 src/open_inwoner/js/components/tab-panels/index.js create mode 100644 src/open_inwoner/scss/components/LoginForm/LoginForm.scss diff --git a/src/eherkenning/tests/test_mock_views.py b/src/eherkenning/tests/test_mock_views.py index 3288f4673d..00778fc6dc 100644 --- a/src/eherkenning/tests/test_mock_views.py +++ b/src/eherkenning/tests/test_mock_views.py @@ -45,7 +45,7 @@ class TestAppIndexTests(TestCase): def test_eherkenning_enabled(self, mock_solo): mock_solo.return_value.eherkenning_enabled = True - url = reverse("login_business") + url = reverse("login") response = self.client.get(url) self.assertEqual(response.status_code, 200) @@ -54,7 +54,7 @@ def test_eherkenning_enabled(self, mock_solo): def test_eherkenning_disabled(self, mock_solo): mock_solo.return_value.eherkenning_enabled = False - url = reverse("login_business") + url = reverse("login") response = self.client.get(url) self.assertEqual(response.status_code, 200) diff --git a/src/open_inwoner/accounts/templates/django_registration/registration_form.html b/src/open_inwoner/accounts/templates/django_registration/registration_form.html index 7c62d9a047..07cb984914 100644 --- a/src/open_inwoner/accounts/templates/django_registration/registration_form.html +++ b/src/open_inwoner/accounts/templates/django_registration/registration_form.html @@ -11,7 +11,7 @@

{% trans 'Registreren' %}

- {% link bold=True href=digid_url text=_('Registreren met DigiD') secondary=True icon='arrow_forward' %} + {% link bold=True href=digid_url text=_('Registreren met DigiD') primary=True icon='arrow_forward' %} {% endrender_card %} {% endrender_column %} {% endif %} @@ -22,7 +22,7 @@

{% trans 'Registreren' %}

- {% link bold=True href=eherkenning_url text=_('Registreren met eHerkenning') secondary=True icon='arrow_forward' %} + {% link bold=True href=eherkenning_url text=_('Registreren met eHerkenning') primary=True icon='arrow_forward' %} {% endrender_card %} {% endrender_column %} {% endif %} diff --git a/src/open_inwoner/accounts/templates/registration/login.html b/src/open_inwoner/accounts/templates/registration/login.html index 52d58a9490..3afc9e7148 100644 --- a/src/open_inwoner/accounts/templates/registration/login.html +++ b/src/open_inwoner/accounts/templates/registration/login.html @@ -17,8 +17,8 @@

{% trans 'Welkom' %}

diff --git a/src/open_inwoner/accounts/templates/registration/login_business.html b/src/open_inwoner/accounts/templates/registration/login_business.html deleted file mode 100644 index 5b639400bc..0000000000 --- a/src/open_inwoner/accounts/templates/registration/login_business.html +++ /dev/null @@ -1,64 +0,0 @@ -{% extends 'master.html' %} -{% load i18n static utils grid_tags card_tags form_tags link_tags button_tags icon_tags solo_tags cms_tags %} - - -{% block header_image %} - {% static_placeholder 'login_banner' %} -{% endblock header_image %} - - -{% block content %} - -

{% trans 'Inloggen' %}

- {% if login_text %} -
{{ login_text|markdown|safe }}
- {% endif %} - - {# Tab panels Start #} - - {# Tab panels End #} - -{% endblock content %} diff --git a/src/open_inwoner/accounts/templates/registration/login_email.html b/src/open_inwoner/accounts/templates/registration/login_email.html deleted file mode 100644 index 56d513148d..0000000000 --- a/src/open_inwoner/accounts/templates/registration/login_email.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends 'master.html' %} -{% load i18n static form_tags card_tags link_tags grid_tags button_tags icon_tags %} - -{% block content %} - -

{% trans 'Log in met e-mail adres' %}

- - {# Tab panels Start #} - - {# Tab panels End #} - -{% endblock content %} diff --git a/src/open_inwoner/accounts/tests/test_auth.py b/src/open_inwoner/accounts/tests/test_auth.py index 67dcc6f6c5..2bc07869ad 100644 --- a/src/open_inwoner/accounts/tests/test_auth.py +++ b/src/open_inwoner/accounts/tests/test_auth.py @@ -1660,7 +1660,7 @@ def test_login_page_has_next_url(self): def test_login(self): """Test that a user is successfully logged in.""" - form = self.app.get(reverse("login_email")).forms["login-form"] + form = self.app.get(reverse("login")).forms["login-form"] form["username"] = self.user.email form["password"] = "test" form.submit().follow() @@ -1706,7 +1706,7 @@ def test_login_page_shows_correct_eherkenning_login_url(self): else f"{reverse('eherkenning:login')}?next=" ) - response = self.app.get(reverse("login_business")) + response = self.app.get(reverse("login")) eherkenning_login_title = _("Inloggen met eHerkenning") eherkenning_login_link = response.pyquery( @@ -1720,7 +1720,7 @@ def test_login_for_inactive_user_shows_appropriate_message(self): self.user.is_active = False self.user.save() - form = self.app.get(reverse("login_email")).forms["login-form"] + form = self.app.get(reverse("login")).forms["login-form"] form["username"] = self.user.email form["password"] = "test" response = form.submit() @@ -1735,7 +1735,7 @@ def test_login_for_inactive_user_shows_appropriate_message(self): ) def test_login_with_wrong_credentials_shows_appropriate_message(self): - form = self.app.get(reverse("login_email")).forms["login-form"] + form = self.app.get(reverse("login")).forms["login-form"] form["username"] = self.user.email form["password"] = "wrong_password" response = form.submit() diff --git a/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py b/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py index 473cc87989..2fd7ec827b 100644 --- a/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py +++ b/src/open_inwoner/accounts/tests/test_auth_2fa_sms.py @@ -39,7 +39,7 @@ def test_regular_login_with_2fa_disabled(self, mock_gateway_send): self.config.login_2fa_sms = False self.config.save() - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -54,7 +54,7 @@ def test_regular_login_with_2fa_disabled(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_with_valid_token_succeeds(self, mock_gateway_send): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -76,7 +76,7 @@ def test_login_with_valid_token_succeeds(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_with_invalid_token_fails(self, mock_gateway_send): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -101,7 +101,7 @@ def test_login_with_invalid_token_fails(self, mock_gateway_send): def test_login_fails_with_sms_failure(self, mock_gateway_send): mock_gateway_send.side_effect = GatewayError - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -138,7 +138,7 @@ def test_login_fails_with_sms_failure(self, mock_gateway_send): @override_settings(ACCOUNTS_USER_TOKEN_EXPIRE_TIME=300) def test_login_fails_with_token_timeout(self, mock_gateway_send): with freeze_time("2023-05-22 11:00:00"): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -160,12 +160,11 @@ def test_login_fails_with_token_timeout(self, mock_gateway_send): response = verify_token_form.submit() self.assertRedirects(response, reverse("login")) - # Or to view reverse("login") ? @patch("open_inwoner.accounts.gateways.gateway.send") def test_login_token_with_max_attempts(self, mock_gateway_send): with freeze_time("2023-05-22 12:00:00") as frozen_time: - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() # login form @@ -205,7 +204,7 @@ def test_login_token_with_max_attempts(self, mock_gateway_send): frozen_time.tick(delta=datetime.timedelta(minutes=-1)) other_user = UserFactory(email="ex2@example.com", password="secret2") - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) login_form = response.forms["login-form"] login_form["username"] = other_user.email login_form["password"] = "secret2" @@ -230,7 +229,7 @@ def test_login_token_with_max_attempts(self, mock_gateway_send): @patch("open_inwoner.accounts.gateways.gateway.send") @freeze_time("2023-05-22 12:00:00") def test_login_when_resending_sms(self, mock_gateway_send): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -276,7 +275,7 @@ def test_login_resend_sms_max_attempts( self, mock_gateway_send, mock_login_throttle_visits ): with freeze_time("2023-05-22 12:00:00"): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() login_form = response.forms["login-form"] @@ -326,7 +325,7 @@ def test_login_resend_sms_max_attempts( # new attempt 5 minutes later with freeze_time("2023-05-22 12:05:01"): - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) login_form = response.forms["login-form"] login_form["username"] = self.user.email login_form["password"] = "secret" @@ -387,7 +386,7 @@ def test_login_by_adding_phone_number_succeeds(self, mock_gateway_send): self.user.phonenumber = "" self.user.save() - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() form = response.forms["login-form"] @@ -425,7 +424,7 @@ def test_login_fails_with_different_phonenumbers(self, mock_gateway_send): self.user.phonenumber = "" self.user.save() - response = self.app.get(reverse("login_email")) + response = self.app.get(reverse("login")) mock_gateway_send.assert_not_called() form = response.forms["login-form"] diff --git a/src/open_inwoner/accounts/views/__init__.py b/src/open_inwoner/accounts/views/__init__.py index 3f119e4ded..8517315ec7 100644 --- a/src/open_inwoner/accounts/views/__init__.py +++ b/src/open_inwoner/accounts/views/__init__.py @@ -30,7 +30,6 @@ from .invite import InviteAcceptView from .login import ( AddPhoneNumberWizardView, - CustomBusinessLoginView, CustomLoginView, ResendTokenView, VerifyTokenView, @@ -72,7 +71,6 @@ "InviteAcceptView", "AddPhoneNumberWizardView", "CustomLoginView", - "CustomBusinessLoginView", "ResendTokenView", "VerifyTokenView", "PasswordResetView", diff --git a/src/open_inwoner/accounts/views/login.py b/src/open_inwoner/accounts/views/login.py index d001396835..f2e52eea93 100644 --- a/src/open_inwoner/accounts/views/login.py +++ b/src/open_inwoner/accounts/views/login.py @@ -91,14 +91,6 @@ def form_valid(self, form): return redirect(furl(reverse("verify_token")).add(params).url) -class CustomEmailLoginView(CustomLoginView): - template_name = "registration/login_email.html" - - -class CustomBusinessLoginView(CustomLoginView): - template_name = "registration/login_business.html" - - class VerifyTokenView(ThrottleMixin, FormView): throttle_visits = 3 throttle_period = 60 diff --git a/src/open_inwoner/js/components/form/LoginForm.js b/src/open_inwoner/js/components/form/LoginForm.js new file mode 100644 index 0000000000..f87d4dc011 --- /dev/null +++ b/src/open_inwoner/js/components/form/LoginForm.js @@ -0,0 +1,83 @@ +export class LoginFormFocus { + static selector = '#login-form' + + constructor(node) { + this.node = node + this.usernameInput = node.querySelector('input[name="username"]') + this.loginFormColumn = document.getElementById('column__login-form') + this.emailToggleParent = document.getElementById('column__email-toggle') + + this.removeAutofocusAndFocus() + this.hideLoginFormOnLoad() + this.addEmailToggleListener() + this.activateTabFromHash() + } + + removeAutofocusAndFocus() { + if (this.usernameInput) { + this.usernameInput.removeAttribute('autofocus') + this.usernameInput.blur() + } + } + + hideLoginFormOnLoad() { + if (this.loginFormColumn) { + this.emailToggleParent.setAttribute('aria-expanded', 'false') + this.loginFormColumn.classList.add('hide') + } + } + + addEmailToggleListener() { + if (this.emailToggleParent) { + const emailToggleParents = + this.emailToggleParent.querySelectorAll('.link') + emailToggleParents.forEach((link) => { + link.addEventListener('click', (event) => { + event.preventDefault() + this.emailToggleParent.classList.add('hide') + this.toggleLoginFormVisibility() + }) + }) + } + } + + toggleLoginFormVisibility() { + if (this.loginFormColumn) { + this.loginFormColumn.classList.toggle('hide') + this.usernameInput.focus() + } + } + + activateTabFromHash() { + const hash = window.location.hash + const particulierLink = document.querySelector( + '.tab__header[href="/accounts/login/#particulier"]' + ) + const zakelijkLink = document.querySelector( + '.tab__header[href="/accounts/login/#zakelijk"]' + ) + const particulierTab = document.getElementById('particulier') + const zakelijkTab = document.getElementById('zakelijk') + + if (hash.includes('zakelijk')) { + particulierLink.classList.remove('active') + particulierTab.classList.remove('active') + particulierTab.classList.add('hide') + + zakelijkTab.classList.remove('hide') + zakelijkTab.classList.add('active') + zakelijkLink.classList.add('active') + } else { + particulierTab.classList.remove('hide') + particulierLink.classList.add('active') + particulierTab.classList.remove('active') + + zakelijkTab.classList.add('hide') + zakelijkTab.classList.remove('active') + zakelijkLink.classList.remove('active') + } + } +} + +const loginformFocuses = document.querySelectorAll(LoginFormFocus.selector) +;[...loginformFocuses].forEach((element) => new LoginFormFocus(element)) diff --git a/src/open_inwoner/js/components/form/index.js b/src/open_inwoner/js/components/form/index.js index 019a738f9c..645926ca79 100644 --- a/src/open_inwoner/js/components/form/index.js +++ b/src/open_inwoner/js/components/form/index.js @@ -2,3 +2,4 @@ import './FileInput' import './ChoiceListMultiple' import './ChoiceListSingle' import './DisableContactFormButton' +import './LoginForm' diff --git a/src/open_inwoner/js/components/index.js b/src/open_inwoner/js/components/index.js index 604d973bba..26a0e38111 100644 --- a/src/open_inwoner/js/components/index.js +++ b/src/open_inwoner/js/components/index.js @@ -27,6 +27,7 @@ import './plan-preview' import './questionnaire' import './readmore' import './search' +import { TabPanel } from './tab-panels' import './toggle' import { StatusAccordion } from './cases/status_accordion' import './session' @@ -58,6 +59,8 @@ const elementWrappers = [ [StatusAccordion.selector, (elt) => new StatusAccordion(elt)], [FileInput.selector, (elt) => new FileInput(elt)], [ToggleHide.selector, (elt) => new ToggleHide(elt)], + [TabPanel.selector, (elt) => new TabPanel(elt)], + // add more when needed ] // harden against multiple events diff --git a/src/open_inwoner/js/components/tab-panels/index.js b/src/open_inwoner/js/components/tab-panels/index.js new file mode 100644 index 0000000000..b533fc534b --- /dev/null +++ b/src/open_inwoner/js/components/tab-panels/index.js @@ -0,0 +1,72 @@ +export class TabPanel { + static selector = '.login-tab--container' + + constructor(node) { + this.node = node + this.tabHeadersRow = node.querySelector('.tabs__headers') + this.tabHeaders = node.querySelectorAll('.tab__header') + this.tabContent = node.querySelectorAll('.tab__content') + + this.tabHeadersRow.addEventListener('click', (e) => { + e.preventDefault() // Prevent 'other' tab__panel from disappearing immediately + + const target = e.target.closest('.tab__header') + if (target) { + const index = [...this.tabHeaders].indexOf(target) + if (index !== -1) { + this.hideContent() + this.showContent(index) + } + } + }) + } + + hideContent() { + this.tabContent.forEach((item) => { + item.classList.add('hide') + item.classList.remove('active') + }) + this.tabHeaders.forEach((item) => { + item.classList.remove('active') + }) + } + + showContent(index = 0) { + this.tabContent.forEach((item, idx) => { + if (idx === index) { + item.classList.remove('hide') + item.classList.add('active') + } else { + item.classList.add('hide') + item.classList.remove('active') + } + }) + this.tabHeaders.forEach((item, idx) => { + if (idx === index) { + item.classList.add('active') + } else { + item.classList.remove('active') + } + }) + } +} + +const tabpanels = document.querySelectorAll(TabPanel.selector) +;[...tabpanels].forEach((tabpanel) => new TabPanel(tabpanel)) + +// Activate tab from hash on page load +// Relies on instantiated TabPanel instances +window.addEventListener('load', () => { + const hash = window.location.hash + if (hash) { + const tabHeader = document.querySelector(`.tab__header[href="${hash}"]`) + if (tabHeader) { + const index = [...tabHeader.parentNode.children].indexOf(tabHeader) + const tabPanel = tabHeader.closest('.tab--container') + const tabPanelInstance = tabPanel && tabPanel.TabPanel + if (tabPanelInstance) { + tabPanelInstance.showContent(index) + } + } + } +}) diff --git a/src/open_inwoner/scss/components/LoginForm/LoginForm.scss b/src/open_inwoner/scss/components/LoginForm/LoginForm.scss new file mode 100644 index 0000000000..22847911d3 --- /dev/null +++ b/src/open_inwoner/scss/components/LoginForm/LoginForm.scss @@ -0,0 +1,7 @@ +#login-form { + //display: none; + + &.active { + display: grid; + } +} diff --git a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss index c9c4c72111..38e75e5743 100644 --- a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss +++ b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss @@ -72,6 +72,7 @@ &:target { scroll-margin-top: 150px; } + &:target::before { scroll-margin-top: 150px; } @@ -92,17 +93,14 @@ .tab__content.active { margin: 1em; scroll-margin-top: 150px; - - p { - padding: 0; - } } .active { display: block; } - .hide { + .hide, + &.hide { display: none; } @@ -182,12 +180,32 @@ font-size: var(--font-size-body); } } + + &#particulier { + #column__email-toggle, + #column__login-form { + &.hide { + display: none; + } + } + + #column__login-form .button--transparent { + color: var(--color-primary); + padding-left: 0; + } + } } -} -/// Tabs voor login pages -.login-tab--container { .tab-column__paragraph { - color: var(--color-gray-dark-900); + color: var(--font-color-body); + font-family: var(--font-family-body); + font-size: var(--font-size-body); + line-height: var(--font-line-height-body); + font-weight: normal; + margin: 0; + } + + .form__actions--single { + max-width: var(--form-width); } } diff --git a/src/open_inwoner/scss/components/_index.scss b/src/open_inwoner/scss/components/_index.scss index 810a1cb588..cebb0fc69d 100644 --- a/src/open_inwoner/scss/components/_index.scss +++ b/src/open_inwoner/scss/components/_index.scss @@ -58,6 +58,7 @@ @import './KCMSurvey/KCMSurvey.scss'; @import './List/List.scss'; @import './List/ListItem.scss'; +@import './LoginForm/LoginForm'; @import './Logo/DigidLogo.scss'; @import './Logo/Logo.scss'; @import './MainImage/MainImage.scss'; diff --git a/src/open_inwoner/scss/views/_view.scss b/src/open_inwoner/scss/views/_view.scss index 1e4eadc72b..15464085f8 100644 --- a/src/open_inwoner/scss/views/_view.scss +++ b/src/open_inwoner/scss/views/_view.scss @@ -27,4 +27,13 @@ color: var(--color-primary); } } + + &---django_registration_register { + .label__label--required { + color: var(--color-red); + padding-left: var(--spacing-tiny); + //make asterisks invisible by default, only make them visible if component has the caption + display: inline; + } + } } diff --git a/src/open_inwoner/templates/registration/password_reset_form.html b/src/open_inwoner/templates/registration/password_reset_form.html index 58f863fe8a..e924648814 100644 --- a/src/open_inwoner/templates/registration/password_reset_form.html +++ b/src/open_inwoner/templates/registration/password_reset_form.html @@ -1,15 +1,20 @@ {% extends 'master.html' %} -{% load i18n static form_tags %} +{% load i18n static grid_tags form_tags %} {% block content %} -

{% trans "Reset password" %}

-

{% trans "Forgot your password? Enter your email address below. Then you will receive an email with instructions to set a new password." %}

-

{% trans "Please note: this only works if you do are not using DigiD to log in." %}

- - {% render_form id="password-reset-form" method="POST" form=form%} - {% csrf_token %} - {% input form.email %} - {% form_actions primary_text=_("Reset password") primary_icon="arrow_forward" %} - {% endrender_form %} + + {% render_grid %} + {% render_column start=0 span=6 %} +

{% trans "Reset password" %}

+

{% trans "Forgot your password? Enter your email address below. Then you will receive an email with instructions to set a new password." %}

+

{% trans "Please note: this only works if you do are not using DigiD to log in." %}

+ + {% render_form id="password-reset-form" method="POST" form=form %} + {% csrf_token %} + {% input form.email %} + {% form_actions primary_text=_("Reset password") primary_icon="arrow_forward" %} + {% endrender_form %} + {% endrender_column %} + {% endrender_grid %} {% endblock content %} diff --git a/src/open_inwoner/urls.py b/src/open_inwoner/urls.py index c3084a342d..2e7b3c0ce6 100644 --- a/src/open_inwoner/urls.py +++ b/src/open_inwoner/urls.py @@ -15,7 +15,6 @@ from open_inwoner.accounts.forms import CustomRegistrationForm from open_inwoner.accounts.views import ( AddPhoneNumberWizardView, - CustomBusinessLoginView, CustomDigiDAssertionConsumerServiceMockView, CustomDigiDAssertionConsumerServiceView, CustomeHerkenningAssertionConsumerServiceMockView, @@ -29,7 +28,6 @@ ResendTokenView, VerifyTokenView, ) -from open_inwoner.accounts.views.login import CustomEmailLoginView from open_inwoner.openklant.views.contactform import ContactFormView from open_inwoner.pdc.views import FAQView @@ -90,16 +88,6 @@ name="password_reset_confirm", ), path("accounts/login/", CustomLoginView.as_view(), name="login"), - path( - "accounts/login-email/", - CustomEmailLoginView.as_view(), - name="login_email", - ), - path( - "accounts/login-business/", - CustomBusinessLoginView.as_view(), - name="login_business", - ), path("accounts/verify/", VerifyTokenView.as_view(), name="verify_token"), path("accounts/resend-token/", ResendTokenView.as_view(), name="resend_token"), path( @@ -194,6 +182,7 @@ path("eherkenning/idp/", include("eherkenning.mock.idp.eherkenning_urls")), ] + urlpatterns + if settings.DEBUG: urlpatterns = [ # provide default styling template From dfd16d921a714ec50c62f74e294d4a3600693c3e Mon Sep 17 00:00:00 2001 From: Jiro Ghianni Date: Thu, 18 Apr 2024 17:17:48 +0200 Subject: [PATCH 3/5] [#2036] Fixed missing 'next' parameter in link tags --- .../templates/registration/login.html | 46 ++++++++++--------- .../scss/components/Logo/DigidLogo.scss | 2 +- .../scss/components/TabPanel/TabPanel.scss | 4 ++ .../scss/components/Typography/Link.scss | 2 +- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/open_inwoner/accounts/templates/registration/login.html b/src/open_inwoner/accounts/templates/registration/login.html index 3afc9e7148..224cc1af90 100644 --- a/src/open_inwoner/accounts/templates/registration/login.html +++ b/src/open_inwoner/accounts/templates/registration/login.html @@ -36,7 +36,9 @@

{% trans 'Welkom' %}

DigiD inlogpagina {% url 'digid_oidc:init' as href %} - {% link href=href text=_('Inloggen met DigiD') primary=True icon='east' extra_classes="link--next link--digid" %} + {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met DigiD') primary=True icon='east' extra_classes="link--next link--digid" %} + {% endwith %} {% endrender_card %} {% else %} {% render_card direction='horizontal' tinted=True compact=True %} @@ -85,20 +87,20 @@

{% trans 'Welkom' %}

{# Hide mail login initially #} -
- {% if login_allow_registration %} - {% render_card tinted=True compact=True %} - {% render_form id="login-form" method="POST" form=form show_required=True %} - {% csrf_token %} - - {% input form.username %} - {% input form.password %} - {% button text=_('Wachtwoord vergeten?') href='password_reset' secondary=True transparent=True align='right' %} - {% form_actions primary_text=_("Inloggen") primary_icon="arrow_forward" single=True %} - {% endrender_form %} - {% endrender_card %} - {% endif %} -
+
+ {% if login_allow_registration %} + {% render_card tinted=True compact=True %} + {% render_form id="login-form" method="POST" form=form show_required=True %} + {% csrf_token %} + + {% input form.username %} + {% input form.password %} + {% button text=_('Wachtwoord vergeten?') href='password_reset' secondary=True transparent=True align='right' %} + {% form_actions primary_text=_("Inloggen") primary_icon="east" single=True %} + {% endrender_form %} + {% endrender_card %} + {% endif %} +
{# End hidden #} {% render_column start=4 span=5 %} @@ -128,21 +130,23 @@

Of registreer

{% if eherkenning_enabled %} {% get_solo 'digid_eherkenning_oidc_generics.OpenIDConnectEHerkenningConfig' as eherkenning_oidc_config %} {% if eherkenning_oidc_config.enabled %} - {% render_card direction='horizontal' tinted=True %} + {% render_card direction='horizontal' tinted=True compact=True %} {% url 'eherkenning_oidc:init' as href %} - {% link href=href text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--next link--eherkenning" %} + {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--eherkenning" %} + {% endwith %} {% endrender_card %} {% else %} - {% render_card direction='horizontal' tinted=True %} + {% render_card direction='horizontal' tinted=True compact=True %} {% url 'eherkenning:login' as href %} {% with href|addnexturl:next as href_with_next %} - {% link href=href_with_next text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--next link--eherkenning" %} + {% link href=href_with_next text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--eherkenning" %} {% endwith %} {% endrender_card %} {% endif %} diff --git a/src/open_inwoner/scss/components/Logo/DigidLogo.scss b/src/open_inwoner/scss/components/Logo/DigidLogo.scss index 13eaf730ad..0870da310b 100644 --- a/src/open_inwoner/scss/components/Logo/DigidLogo.scss +++ b/src/open_inwoner/scss/components/Logo/DigidLogo.scss @@ -1,5 +1,5 @@ .digid-logo { &__image { - height: 40px; + height: 50px; } } diff --git a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss index 38e75e5743..9eb94c2fe9 100644 --- a/src/open_inwoner/scss/components/TabPanel/TabPanel.scss +++ b/src/open_inwoner/scss/components/TabPanel/TabPanel.scss @@ -175,6 +175,10 @@ margin-bottom: var(--spacing-large); } + .grid { + gap: var(--spacing-large); + } + .card { & .link--next [class*='icon'] { font-size: var(--font-size-body); diff --git a/src/open_inwoner/scss/components/Typography/Link.scss b/src/open_inwoner/scss/components/Typography/Link.scss index 5de5e6f747..2fac1e5cee 100644 --- a/src/open_inwoner/scss/components/Typography/Link.scss +++ b/src/open_inwoner/scss/components/Typography/Link.scss @@ -85,7 +85,7 @@ *[class*='icon'] { color: var(--color-gray-90); - font-size: 46px; + font-size: 50px; } } From dcb8f2f03d5c693312cf85960ba1b79e4d63898c Mon Sep 17 00:00:00 2001 From: Bart van der Schoor Date: Fri, 19 Apr 2024 09:47:42 +0200 Subject: [PATCH 4/5] [#2036] Fixed missing next urls --- .../templates/registration/login.html | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/open_inwoner/accounts/templates/registration/login.html b/src/open_inwoner/accounts/templates/registration/login.html index 224cc1af90..1f15dc7fca 100644 --- a/src/open_inwoner/accounts/templates/registration/login.html +++ b/src/open_inwoner/accounts/templates/registration/login.html @@ -32,21 +32,21 @@

{% trans 'Welkom' %}

{% get_solo 'digid_eherkenning_oidc_generics.OpenIDConnectDigiDConfig' as digid_oidc_config %} {% if digid_oidc_config.enabled %} {% render_card direction='horizontal' tinted=True compact=True %} - {% url 'digid_oidc:init' as href %} {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met DigiD') primary=True icon='east' extra_classes="link--next link--digid" %} {% endwith %} {% endrender_card %} {% else %} {% render_card direction='horizontal' tinted=True compact=True %} - {% url 'digid:login' as href %} {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met DigiD') primary=True icon='east' extra_classes="link--next link--digid" %} {% endwith %} {% endrender_card %} @@ -60,16 +60,16 @@

{% trans 'Welkom' %}

{% get_solo 'configurations.SiteConfiguration' as site_config %} {% if oidc_config.enabled and site_config.openid_enabled_for_regular_users %} {% render_column start=4 span=5 %} - {% render_card tinted=True compact=True direction='horizontal' %} - {% if site_config.openid_connect_logo %} - - {% else %} -
- {% endif %} + {% render_card tinted=True compact=True direction='horizontal' %} {% url 'oidc_authentication_init' as href %} {% with href|addnexturl:next as href_with_next %} + {% if site_config.openid_connect_logo %} + + {% else %} +
+ {% endif %} {% link text=site_config.openid_connect_login_text href=href_with_next primary=True icon='east' icon_position="after" extra_classes="link--next link--oidc" %} {% endwith %} {% endrender_card %} @@ -131,21 +131,21 @@

Of registreer

{% get_solo 'digid_eherkenning_oidc_generics.OpenIDConnectEHerkenningConfig' as eherkenning_oidc_config %} {% if eherkenning_oidc_config.enabled %} {% render_card direction='horizontal' tinted=True compact=True %} - {% url 'eherkenning_oidc:init' as href %} {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--eherkenning" %} {% endwith %} {% endrender_card %} {% else %} {% render_card direction='horizontal' tinted=True compact=True %} - {% url 'eherkenning:login' as href %} {% with href|addnexturl:next as href_with_next %} + {% link href=href_with_next text=_('Inloggen met eHerkenning') primary=True icon='east' extra_classes="link--eherkenning" %} {% endwith %} {% endrender_card %} From c959b4f914600d9161b8ecb8f6a58d8e3f56e812 Mon Sep 17 00:00:00 2001 From: Bart van der Schoor Date: Fri, 19 Apr 2024 10:04:58 +0200 Subject: [PATCH 5/5] [#2036] Fixed reversed URls --- .../accounts/templates/registration/login.html | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/open_inwoner/accounts/templates/registration/login.html b/src/open_inwoner/accounts/templates/registration/login.html index 1f15dc7fca..a3e23c12a9 100644 --- a/src/open_inwoner/accounts/templates/registration/login.html +++ b/src/open_inwoner/accounts/templates/registration/login.html @@ -17,8 +17,8 @@

{% trans 'Welkom' %}