0.2.3 #99

Merged
sonny merged 112 commits from development into master 2020-05-23 16:58:42 +02:00
16 changed files with 179 additions and 10 deletions
Showing only changes of commit 13d33749da - Show all commits

View file

@ -0,0 +1,9 @@
from django import forms
from newsreader.accounts.models import User
class UserSettingsForm(forms.ModelForm):
class Meta:
model = User
fields = ("first_name", "last_name")

View file

@ -0,0 +1,22 @@
{% extends "base.html" %}
{% load static i18n %}
{% block content %}
<main class="main">
<form class="form password-change-form" method="post">
{% csrf_token %}
<div class="form__header">
<h1 class="h1 form__title">{% trans "Password change" %}</h1>
</div>
<fieldset class="fieldset password-change-form__fieldset">
{{ form }}
</fieldset>
<fieldset class="fieldset password-reset-form__fieldset">
<a class="button button--cancel" href="{% url 'accounts:settings' %}">Cancel</a>
<button class="button button--confirm" type="submit">Change</button>
</fieldset>
</form>
</main>
{% endblock %}

View file

@ -0,0 +1,42 @@
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<main id="settings--page" class="main">
<form class="form settings-form" method="post">
{% csrf_token %}
<div class="form__header">
<h1 class="h1 form__title">{% trans "User settings" %}</h1>
</div>
{{ form.non_field_errors }}
<section class="section form__section settings-form__section">
<fieldset class="form__fieldset settings-form__fieldset">
<label class="label settings-form__label" for="first_name">{% trans "First name" %}</label>
{{ form.first_name.errors }}
{{ form.first_name }}
</fieldset>
<fieldset class="form__fieldset settings-form__fieldset">
<label class="label settings-form__label" for="last_name">{% trans "Last name" %}</label>
{{ form.last_name.errors }}
{{ form.last_name }}
</fieldset>
</section>
<section class="section form__section settings-form__section">
<fieldset class="form__fieldset settings-form__fieldset">
<a class="link button button--cancel" href="{% url 'index' %}">Cancel</a>
<span class="span">
<a class="link button button--primary" href="{% url 'accounts:password-change' %}">
{% trans "Change password" %}
</a>
<button class="button button--confirm">Save</button>
</span>
</fieldset>
</section>
</form>
</main>
{% endblock %}

View file

@ -0,0 +1,29 @@
from django.test import TestCase
from django.urls import reverse
from newsreader.accounts.models import User
from newsreader.accounts.tests.factories import UserFactory
class UserSettingsViewTestCase(TestCase):
def setUp(self):
self.user = UserFactory(password="test")
self.client.force_login(self.user)
def test_simple(self):
response = self.client.get(reverse("accounts:settings"))
self.assertEquals(response.status_code, 200)
def test_user_credential_change(self):
response = self.client.post(
reverse("accounts:settings"),
{"first_name": "First name", "last_name": "Last name"},
)
user = User.objects.get()
self.assertRedirects(response, reverse("accounts:settings"))
self.assertEquals(user.first_name, "First name")
self.assertEquals(user.last_name, "Last name")

View file

@ -1,3 +1,4 @@
from django.contrib.auth.decorators import login_required
from django.urls import path from django.urls import path
from newsreader.accounts.views import ( from newsreader.accounts.views import (
@ -6,6 +7,7 @@ from newsreader.accounts.views import (
ActivationView, ActivationView,
LoginView, LoginView,
LogoutView, LogoutView,
PasswordChangeView,
PasswordResetCompleteView, PasswordResetCompleteView,
PasswordResetConfirmView, PasswordResetConfirmView,
PasswordResetDoneView, PasswordResetDoneView,
@ -13,6 +15,7 @@ from newsreader.accounts.views import (
RegistrationClosedView, RegistrationClosedView,
RegistrationCompleteView, RegistrationCompleteView,
RegistrationView, RegistrationView,
SettingsView,
) )
@ -52,5 +55,10 @@ urlpatterns = [
PasswordResetCompleteView.as_view(), PasswordResetCompleteView.as_view(),
name="password-reset-complete", name="password-reset-complete",
), ),
# TODO: create password change views path(
"password-change/",
login_required(PasswordChangeView.as_view()),
name="password-change",
),
path("settings/", login_required(SettingsView.as_view()), name="settings"),
] ]

View file

@ -2,15 +2,17 @@ from django.contrib.auth import views as django_views
from django.shortcuts import render from django.shortcuts import render
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views.generic.edit import FormView, ModelFormMixin
from registration.backends.default import views as registration_views from registration.backends.default import views as registration_views
from newsreader.accounts.forms import UserSettingsForm
from newsreader.accounts.models import User
class LoginView(django_views.LoginView): class LoginView(django_views.LoginView):
template_name = "accounts/login.html" template_name = "accounts/login.html"
success_url = reverse_lazy("index")
def get_success_url(self):
return reverse_lazy("index")
class LogoutView(django_views.LogoutView): class LogoutView(django_views.LogoutView):
@ -89,3 +91,25 @@ class PasswordResetConfirmView(django_views.PasswordResetConfirmView):
class PasswordResetCompleteView(django_views.PasswordResetCompleteView): class PasswordResetCompleteView(django_views.PasswordResetCompleteView):
template_name = "password-reset/password_reset_complete.html" template_name = "password-reset/password_reset_complete.html"
class PasswordChangeView(django_views.PasswordChangeView):
template_name = "accounts/password_change.html"
success_url = reverse_lazy("accounts:settings")
class SettingsView(ModelFormMixin, FormView):
template_name = "accounts/settings.html"
success_url = reverse_lazy("accounts:settings")
form_class = UserSettingsForm
model = User
def get(self, request, *args, **kwargs):
self.object = self.get_object()
return super().get(request, *args, **kwargs)
def get_object(self, **kwargs):
return self.request.user
def get_form_kwargs(self):
return {**super().get_form_kwargs(), "instance": self.request.user}

View file

@ -80,7 +80,7 @@ class App extends React.Component {
const pageHeader = ( const pageHeader = (
<> <>
<h1 className="h1">Categories</h1> <h1 className="h1">Categories</h1>
<a className="link button button--confirm" href="/categories/create/"> <a className="link button button--confirm" href="/core/categories/create/">
Create category Create category
</a> </a>
</> </>

View file

@ -1,7 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n static %}
{% load static %}
{% block content %} {% block content %}
<main id="rules--page" class="main"> <main id="rules--page" class="main">

View file

@ -0,0 +1,9 @@
.settings-form {
&__section:last-child {
& .settings-form__fieldset {
display: flex;
flex-direction: row;
justify-content: space-between;
}
}
}

View file

@ -11,3 +11,5 @@
@import "password-reset-form"; @import "password-reset-form";
@import "password-reset-confirm-form"; @import "password-reset-confirm-form";
@import "settings-form";

View file

@ -0,0 +1,11 @@
.text-section {
@extend .section;
width: 70%;
border-radius: 5px;
padding: 10px;
background-color: $white;
}

View file

@ -1 +1,2 @@
@import "section"; @import "section";
@import "text-section";

View file

@ -1,3 +1,3 @@
@mixin button-padding { @mixin button-padding {
padding: 10px 50px; padding: 7px 40px;
} }

View file

@ -10,3 +10,5 @@
@import "rule/index"; @import "rule/index";
@import "rules/index"; @import "rules/index";
@import "settings/index";

View file

@ -0,0 +1,12 @@
#settings--page {
.settings-form__fieldset:last-child {
& span {
display: flex;
flex-direction: row;
& >:first-child {
margin: 0 5px;
}
}
}
}

View file

@ -17,7 +17,7 @@
<li class="nav__item"><a href="{% url 'index' %}">Home</a></li> <li class="nav__item"><a href="{% url 'index' %}">Home</a></li>
<li class="nav__item"><a href="{% url 'news:core:categories' %}">Categories</a></li> <li class="nav__item"><a href="{% url 'news:core:categories' %}">Categories</a></li>
<li class="nav__item"><a href="{% url 'news:collection:rules' %}">Feeds</a></li> <li class="nav__item"><a href="{% url 'news:collection:rules' %}">Feeds</a></li>
<li class="nav__item"><a href="#">Settings</a></li> <li class="nav__item"><a href="{% url 'accounts:settings' %}">Settings</a></li>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
<li class="nav__item"><a href="{% url 'admin:index' %}">Admin</a></li> <li class="nav__item"><a href="{% url 'admin:index' %}">Admin</a></li>
{% endif %} {% endif %}