This commit is contained in:
Herculino Trotta
2024-10-09 00:31:21 -03:00
parent e78e4cc5e1
commit 3dde44b1cd
139 changed files with 4965 additions and 1004 deletions

View File

@@ -5,24 +5,31 @@ from django.contrib.auth.forms import (
AdminPasswordChangeForm,
)
from django.utils.translation import gettext_lazy as _
from django.contrib import admin
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import Group
from apps.users.models import User
from apps.users.models import User, UserSettings
admin.site.unregister(Group)
class UserSettingsInline(admin.StackedInline):
model = UserSettings
can_delete = False
extra = 0
verbose_name_plural = _("User Settings")
verbose_name = _("User Setting")
@admin.register(User)
class UserAdmin(BaseUserAdmin, ModelAdmin):
ordering = ("email",)
exclude = ("username",)
list_display = ("email", "is_staff")
search_fields = ("first_name", "last_name", "email")
inlines = (UserSettingsInline,)
form = UserChangeForm
add_form = UserCreationForm
@@ -67,3 +74,6 @@ class UserAdmin(BaseUserAdmin, ModelAdmin):
@admin.register(Group)
class GroupAdmin(BaseGroupAdmin, ModelAdmin):
pass
admin.site.register(UserSettings)

View File

@@ -14,20 +14,18 @@ from django.contrib.auth.forms import (
SetPasswordForm,
PasswordChangeForm,
UserCreationForm,
AuthenticationForm,
)
from django.core.exceptions import ValidationError
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _
from django_recaptcha.fields import ReCaptchaField
from django_recaptcha.widgets import ReCaptchaV3
from unfold.forms import AuthenticationForm
class LoginForm(AuthenticationForm):
username = UsernameField(
label="Seu e-mail",
widget=forms.TextInput(
attrs={"class": "form-control", "placeholder": "E-mail"}
widget=forms.EmailInput(
attrs={"class": "form-control", "placeholder": "E-mail", "name": "email"}
),
)
password = forms.CharField(
@@ -39,6 +37,16 @@ class LoginForm(AuthenticationForm):
)
error_messages = {
"invalid_login": _("E-mail ou senha inválidos."),
"inactive": _("Esta conta esta desativada."),
"invalid_login": _("Invalid e-mail or password"),
"inactive": _("This account is deactivated"),
}
def __init__(self, request=None, *args, **kwargs):
super().__init__(request, *args, **kwargs)
self.helper = FormHelper()
self.helper.layout = Layout(
"username",
"password",
Submit("Submit", "Login"),
)

View File

@@ -0,0 +1,23 @@
# Generated by Django 5.1.1 on 2024-10-07 00:17
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='UserSettings',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('hide_amounts', models.BooleanField(default=False)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='settings', to=settings.AUTH_USER_MODEL)),
],
),
]

View File

@@ -1,4 +1,5 @@
from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
from django.contrib.auth.models import AbstractUser, Group
from django.utils.translation import gettext_lazy as _
@@ -17,3 +18,13 @@ class User(AbstractUser):
def __str__(self):
return f"{self.first_name} {self.last_name} ({self.email})"
class UserSettings(models.Model):
user = models.OneToOneField(
get_user_model(), on_delete=models.CASCADE, related_name="settings"
)
hide_amounts = models.BooleanField(default=False)
def __str__(self):
return f"{self.user.email}'s settings"

18
app/apps/users/signals.py Normal file
View File

@@ -0,0 +1,18 @@
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from apps.users.models import UserSettings
User = get_user_model()
@receiver(post_save, sender=User)
def create_user_settings(sender, instance, created, **kwargs):
if created:
UserSettings.objects.create(user=instance)
@receiver(post_save, sender=User)
def save_user_settings(sender, instance, **kwargs):
instance.settings.save()

View File

@@ -6,4 +6,9 @@ urlpatterns = [
path("login/", views.UserLoginView.as_view(), name="login"),
# path("login/fallback/", views.UserLoginView.as_view(), name="fallback_login"),
path("logout/", views.logout_view, name="logout"),
path(
"user/toggle-amount-visibility/",
views.toggle_amount_visibility,
name="toggle_amount_visibility",
),
]

View File

@@ -1,23 +1,48 @@
from django.contrib import messages
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.views import (
LoginView,
)
from django.http import HttpResponse
from django.shortcuts import redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from apps.users.forms import (
LoginForm,
EmailLoginForm,
)
from apps.common.decorators.htmx import only_htmx
def logout_view(request):
logout(request)
return redirect(reverse("inicio"))
return redirect(reverse("login"))
class UserLoginView(LoginView):
form_class = LoginForm
# template_name = "users/login.html"
template_name = "users/login.html"
redirect_authenticated_user = True
@only_htmx
@login_required
def toggle_amount_visibility(request):
current_hide_amounts = request.user.settings.hide_amounts
new_hide_amounts = not current_hide_amounts
request.user.settings.hide_amounts = new_hide_amounts
request.user.settings.save()
if new_hide_amounts is True:
messages.info(request, _("Transaction amounts are now hidden"))
response = HttpResponse(
'<i class="fa-solid fa-eye-slash fa-fw"></i><div id="settings-hide-amounts" class="d-inline tw-invisible"></div>'
)
else:
messages.info(request, _("Transaction amounts are now displayed"))
response = HttpResponse('<i class="fa-solid fa-eye fa-fw"></i>')
response.headers["HX-Trigger"] = "transaction_updated, toast"
return response