diff --git a/src/servala/frontend/forms/__init__.py b/src/servala/frontend/forms/__init__.py
index 8169b61..fe0ffc1 100644
--- a/src/servala/frontend/forms/__init__.py
+++ b/src/servala/frontend/forms/__init__.py
@@ -1,3 +1,4 @@
from .organization import OrganizationCreateForm
+from .profile import UserProfileForm
-__all__ = ["OrganizationCreateForm"]
+__all__ = ["OrganizationCreateForm", "UserProfileForm"]
diff --git a/src/servala/frontend/forms/profile.py b/src/servala/frontend/forms/profile.py
new file mode 100644
index 0000000..23f1df6
--- /dev/null
+++ b/src/servala/frontend/forms/profile.py
@@ -0,0 +1,11 @@
+from django import forms
+
+from servala.core.models import User
+from servala.frontend.forms.mixins import HtmxMixin
+
+
+class UserProfileForm(HtmxMixin, forms.ModelForm):
+
+ class Meta:
+ model = User
+ fields = ("email", "company")
diff --git a/src/servala/frontend/templates/frontend/profile.html b/src/servala/frontend/templates/frontend/profile.html
index 9532e96..7b37956 100644
--- a/src/servala/frontend/templates/frontend/profile.html
+++ b/src/servala/frontend/templates/frontend/profile.html
@@ -1,5 +1,6 @@
{% extends "frontend/base.html" %}
{% load i18n static %}
+{% load partials %}
{% block html_title %}
{% block page_title %}
{% translate "Profile" %}
@@ -10,6 +11,70 @@
{% translate "Account" %}
{% endblock %}
+{% partialdef user-email %}
+
+ {% translate "E-mail" %} |
+ {{ request.user.email }} |
+
+
+ |
+
+{% endpartialdef user-email %}
+{% partialdef user-company %}
+
+ {% translate "Company" %} |
+ {{ request.user.company|default_if_none:"" }} |
+
+
+ |
+
+{% endpartialdef user-company %}
+{% partialdef user-email-edit %}
+
+ {% translate "E-mail" %} |
+
+
+ |
+
+{% endpartialdef %}
+{% partialdef user-company-edit %}
+
+ {% translate "Company" %} |
+
+
+ |
+
+{% endpartialdef %}
{% block content %}
@@ -23,22 +88,18 @@
-
- {% translate "E-mail" %} |
- {{ request.user.email }} |
-
+ {% partial user-email %}
{% translate "First name" %} |
{{ request.user.first_name }} |
+ |
{% translate "Last name" %} |
{{ request.user.last_name }} |
+ |
-
- {% translate "Company" %} |
- {{ request.user.company }} |
-
+ {% partial user-company %}
diff --git a/src/servala/frontend/views/generic.py b/src/servala/frontend/views/generic.py
index 3b2196b..12300fd 100644
--- a/src/servala/frontend/views/generic.py
+++ b/src/servala/frontend/views/generic.py
@@ -1,21 +1,41 @@
from django.conf import settings
-from django.views.generic import TemplateView
+from django.urls import reverse_lazy
+from django.utils.functional import cached_property
+from django.views.generic import TemplateView, UpdateView
+
+from servala.core.models import User
+from servala.frontend.forms.profile import UserProfileForm
+from servala.frontend.views.mixins import HtmxMixin
class IndexView(TemplateView):
template_name = "frontend/index.html"
-class ProfileView(TemplateView):
+class ProfileView(HtmxMixin, UpdateView):
template_name = "frontend/profile.html"
+ form_class = UserProfileForm
+ success_url = reverse_lazy("frontend:profile")
+ fragments = ("user-email", "user-email-edit", "user-company", "user-company-edit")
+ model = User
+
+ def get_object(self):
+ return self.request.user
+
+ @cached_property
+ def object(self):
+ return self.get_object()
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
- keycloak_server_url = settings.SOCIALACCOUNT_PROVIDERS["openid_connect"][
- "APPS"
- ][0]["settings"]["server_url"]
+ keycloak_settings = settings.SOCIALACCOUNT_PROVIDERS["openid_connect"]
+ keycloak_server_url = keycloak_settings["APPS"][0]["settings"]["server_url"]
account_url = keycloak_server_url.replace(
"/.well-known/openid-configuration", "/account"
)
context["account_href"] = account_url
return context
+
+ def form_valid(self, form):
+ form.save()
+ return super().form_valid(form)