snapshot: preserve account profile inline editing and avatar flow

This commit is contained in:
Md Bayazid Bostame
2026-03-27 02:06:52 +01:00
parent 8d228723f9
commit 358a71230d
13 changed files with 1462 additions and 398 deletions

View File

@@ -8,45 +8,220 @@
{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'workflows/css/login.css' %}" />
<link rel="stylesheet" href="{% static 'workflows/css/account.css' %}" />
{% endblock %}
{% block shell_body %}
<section class="login-shell-body">
<div class="login-card account-card">
<h1>{% trans "Profil" %}</h1>
<p>{% trans "Ihre aktuelle Workdock-Kontoübersicht und direkte Kontoaktionen." %}</p>
<section class="account-shell-body">
<div class="account-page">
<section class="account-hero">
<div class="account-hero-copy">
<span class="account-kicker">{% trans "Konto" %}</span>
<h1>{% trans "Profil" %}</h1>
<p>{% trans "Ihre aktuelle Workdock-Kontoübersicht und wichtige Sicherheitsaktionen." %}</p>
</div>
<div class="account-hero-badges">
<span class="account-chip">{{ role_label }}</span>
<span class="account-chip account-chip-muted">{{ account_user.username }}</span>
</div>
</section>
<div class="account-grid">
<div class="account-row">
<span>{% trans "Name" %}</span>
<strong>{{ account_user.get_full_name|default:account_user.username }}</strong>
</div>
<div class="account-row">
<span>{% trans "Benutzername" %}</span>
<strong>{{ account_user.username }}</strong>
</div>
<div class="account-row">
<span>{% trans "E-Mail" %}</span>
<strong>{{ account_user.email|default:"-" }}</strong>
</div>
<div class="account-row">
<span>{% trans "Rolle" %}</span>
<strong>{{ role_label }}</strong>
</div>
<div class="account-row">
<span>{% trans "Letzte Anmeldung" %}</span>
<strong>{% if account_user.last_login %}{{ account_user.last_login|date:"d.m.Y H:i" }}{% else %}-{% endif %}</strong>
</div>
</div>
<div class="account-layout">
<aside class="account-profile-card">
<form class="account-avatar-form" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="account_form" value="avatar" />
<label class="account-avatar-wrap" for="{{ avatar_form.avatar_image.id_for_label }}">
{% if account_user_profile.avatar_image %}
<img class="account-avatar-image" src="{{ account_user_profile.avatar_image.url }}" alt="{% trans 'Profilbild' %}" />
{% else %}
<div class="account-avatar" aria-hidden="true">
{% if account_user.first_name or account_user.last_name %}
{{ account_user.first_name|slice:":1" }}{{ account_user.last_name|slice:":1" }}
{% else %}
{{ account_user.username|slice:":2" }}
{% endif %}
</div>
{% endif %}
<span class="account-avatar-edit" aria-hidden="true"></span>
</label>
<div class="account-avatar-input" hidden>
{{ avatar_form.avatar_image }}
</div>
{% if avatar_form.avatar_image.errors %}
<div class="account-avatar-error">{{ avatar_form.avatar_image.errors|join:", " }}</div>
{% endif %}
<p class="account-avatar-hint">{% trans "Klicken Sie auf das Bild, um ein neues Profilbild auszuwählen." %}</p>
</form>
<div class="account-profile-copy">
<h2>{{ account_user.get_full_name|default:account_user.username }}</h2>
<p>{{ account_user.email|default:account_user.username }}</p>
</div>
<div class="account-profile-meta">
<div>
<span>{% trans "Rolle" %}</span>
<strong>{{ role_label }}</strong>
</div>
<div>
<span>{% trans "Benutzername" %}</span>
<strong>{{ account_user.username }}</strong>
</div>
<div>
<span>{% trans "Position" %}</span>
<strong>{{ account_user_profile.job_title|default:"-" }}</strong>
</div>
<div>
<span>{% trans "Abteilung" %}</span>
<strong>{{ account_user_profile.department|default:"-" }}</strong>
</div>
<div>
<span>{% trans "Letzte Anmeldung" %}</span>
<strong>{% if account_user.last_login %}{{ account_user.last_login|date:"d.m.Y H:i" }}{% else %}-{% endif %}</strong>
</div>
</div>
</aside>
<div class="account-actions">
<a class="btn btn-primary" href="{% url 'password_change' %}">{% trans "Passwort ändern" %}</a>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button class="btn btn-secondary" type="submit">{% trans "Abmelden" %}</button>
</form>
<div class="account-main">
<section class="account-panel">
<div class="account-panel-head">
<div>
<h2>{% trans "Kontodaten" %}</h2>
<p>{% trans "Die wichtigsten Stammdaten Ihres aktuellen Kontos." %}</p>
</div>
<button
class="btn btn-secondary account-inline-edit-trigger"
type="button"
data-account-edit-toggle="details"
aria-expanded="{% if account_edit_open %}true{% else %}false{% endif %}"
>
{% trans "Bearbeiten" %}
</button>
</div>
<div class="account-inline-view{% if account_edit_open %} is-hidden{% endif %}" data-account-edit-view="details">
<div class="account-detail-grid">
<div class="account-detail">
<span>{% trans "Name" %}</span>
<strong>{{ account_user.get_full_name|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "E-Mail" %}</span>
<strong>{{ account_user.email|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Vorname" %}</span>
<strong>{{ account_user.first_name|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Nachname" %}</span>
<strong>{{ account_user.last_name|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Telefon" %}</span>
<strong>{{ account_user_profile.phone_number|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Mobil" %}</span>
<strong>{{ account_user_profile.mobile_number|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Position" %}</span>
<strong>{{ account_user_profile.job_title|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Abteilung" %}</span>
<strong>{{ account_user_profile.department|default:"-" }}</strong>
</div>
<div class="account-detail">
<span>{% trans "Standort" %}</span>
<strong>{{ account_user_profile.location|default:"-" }}</strong>
</div>
<div class="account-detail account-detail-wide">
<span>{% trans "Hinweise" %}</span>
<strong>{{ account_user_profile.contact_notes|default:"-" }}</strong>
</div>
</div>
</div>
<form
class="account-inline-form{% if not account_edit_open %} is-hidden{% endif %}"
method="post"
data-account-edit-form="details"
>
{% csrf_token %}
<input type="hidden" name="account_form" value="details" />
<div class="account-form-grid">
{% for field in details_form %}
<div class="account-form-field{% if field.name == 'contact_notes' %} account-form-field-wide{% endif %}{% if field.errors %} has-error{% endif %}">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
{% if field.errors %}
<div class="account-form-error">{{ field.errors|join:", " }}</div>
{% endif %}
</div>
{% endfor %}
</div>
<div class="account-inline-actions">
<button class="btn btn-primary" type="submit">{% trans "Speichern" %}</button>
<button class="btn btn-secondary" type="button" data-account-edit-cancel="details">{% trans "Abbrechen" %}</button>
</div>
</form>
</section>
<section class="account-panel">
<div class="account-panel-head">
<h2>{% trans "Sicherheit & Aktionen" %}</h2>
<p>{% trans "Direkte Aktionen für Ihr Workdock-Konto." %}</p>
</div>
<div class="account-action-grid">
<a class="account-action-card" href="{% url 'password_change' %}">
<strong>{% trans "Passwort ändern" %}</strong>
<span>{% trans "Aktualisieren Sie Ihr Passwort direkt im Konto." %}</span>
</a>
<div class="account-action-card account-action-card-muted">
<strong>{% trans "Sitzung" %}</strong>
<span>{% trans "Sie können sich jederzeit sicher vom aktuellen Gerät abmelden." %}</span>
</div>
</div>
<div class="account-actions">
<a class="btn btn-primary" href="{% url 'password_change' %}">{% trans "Passwort ändern" %}</a>
<form method="post" action="{% url 'logout' %}">
{% csrf_token %}
<button class="btn btn-secondary" type="submit">{% trans "Abmelden" %}</button>
</form>
</div>
</section>
</div>
</div>
</div>
</section>
{% endblock %}
{% block extra_scripts %}
<script>
(function () {
var toggle = document.querySelector('[data-account-edit-toggle="details"]');
var cancel = document.querySelector('[data-account-edit-cancel="details"]');
var view = document.querySelector('[data-account-edit-view="details"]');
var form = document.querySelector('[data-account-edit-form="details"]');
if (!toggle || !cancel || !view || !form) return;
function setMode(editing) {
view.classList.toggle('is-hidden', editing);
form.classList.toggle('is-hidden', !editing);
toggle.setAttribute('aria-expanded', editing ? 'true' : 'false');
}
toggle.addEventListener('click', function () {
setMode(true);
});
cancel.addEventListener('click', function () {
setMode(false);
});
}());
</script>
{% endblock %}

View File

@@ -23,10 +23,14 @@
<details class="app-user-menu">
<summary class="app-user-trigger">
<span class="app-user-avatar" aria-hidden="true">
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name|slice:":1" }}{{ request.user.last_name|slice:":1" }}
{% if user_avatar_url %}
<img class="app-user-avatar-image" src="{{ user_avatar_url }}" alt="{% trans 'Profilbild' %}" />
{% else %}
{{ request.user.username|slice:":2" }}
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name|slice:":1" }}{{ request.user.last_name|slice:":1" }}
{% else %}
{{ request.user.username|slice:":2" }}
{% endif %}
{% endif %}
</span>
<span class="app-user-copy">