|
- {# templates/account/index.html.twig #}
- {% extends 'base.html.twig' %}
-
- {% block title %}
- {% if tab == 'account' %}Account{% else %}Mein Benutzer{% endif %}
- {% endblock %}
-
- {% block body %}
-
- <div class="account-page">
-
- <div class="account-header">
- <h1 class="account-header__title">
- {% if tab == 'account' %}Account{% else %}Mein Benutzer{% endif %}
- </h1>
-
- {% if isAdmin %}
- <nav class="account-tabs">
- <a href="{{ path('account_index', {tab: 'account'}) }}"
- class="account-tab{% if tab == 'account' %} account-tab--active{% endif %}">
- Account
- </a>
- <a href="{{ path('account_index', {tab: 'user'}) }}"
- class="account-tab{% if tab == 'user' %} account-tab--active{% endif %}">
- Mein Benutzer
- </a>
- </nav>
- {% endif %}
- </div>
-
- <div class="account-content">
- <div class="account-card">
-
- {# ── Account-Tab (nur Admin) ────────────────────────────────────────── #}
- {% if tab == 'account' and isAdmin %}
-
- <div class="account-form__grid" id="account-form">
-
- <label class="account-form__label" for="account-name">Firmenname</label>
- <div class="account-form__field">
- <input type="text" id="account-name" class="input"
- value="{{ account.name|e('html_attr') }}" />
- <span class="account-form__hint">
- Subdomain: <strong>{{ account.slug }}.{{ app.request.host|split('.')|slice(1)|join('.') }}</strong> — ändert sich nicht.
- </span>
- </div>
-
- <label class="account-form__label" for="account-interval">Zeitintervall</label>
- <div class="account-form__field">
- <select id="account-interval" class="select">
- {% for value, label in intervalOptions %}
- <option value="{{ value }}"{% if account.trackingInterval == value %} selected{% endif %}>
- {{ label }}
- </option>
- {% endfor %}
- </select>
- <span class="account-form__hint">Auf welche Einheit werden erfasste Zeiten aufgerundet.</span>
- </div>
-
- <div class="account-form__actions">
- <button type="button" class="btn btn-primary" id="btn-account-save">Sichern</button>
- <a href="{{ path('account_index', {tab: 'account'}) }}" class="btn btn-secondary">Abbrechen</a>
- </div>
-
- </div>
-
- {# ── Benutzer-Tab ──────────────────────────────────────────────────── #}
- {% else %}
-
- <div class="account-form__grid" id="user-form">
-
- <label class="account-form__label" for="user-firstname">Vorname</label>
- <div class="account-form__field">
- <input type="text" id="user-firstname" class="input"
- value="{{ user.firstName|e('html_attr') }}" />
- </div>
-
- <label class="account-form__label" for="user-lastname">Nachname</label>
- <div class="account-form__field">
- <input type="text" id="user-lastname" class="input"
- value="{{ user.lastName|e('html_attr') }}" />
- </div>
-
- <label class="account-form__label" for="user-email">E-Mail</label>
- <div class="account-form__field">
- <input type="email" id="user-email" class="input"
- value="{{ user.email|e('html_attr') }}" />
- </div>
-
- <label class="account-form__label">Passwort</label>
- <div class="account-form__field">
- <a href="#" class="account-form__link" id="btn-pw-toggle">ändern</a>
- </div>
-
- <div class="account-form__pw-section" id="pw-section" hidden>
-
- <label class="account-form__label" for="user-pw-current">Aktuelles Passwort</label>
- <div class="account-form__field">
- <input type="password" id="user-pw-current" class="input" autocomplete="current-password" />
- </div>
-
- <label class="account-form__label" for="user-pw-new">Neues Passwort</label>
- <div class="account-form__field">
- <input type="password" id="user-pw-new" class="input" autocomplete="new-password" minlength="8" />
- </div>
-
- <label class="account-form__label" for="user-pw-repeat">Wiederholen</label>
- <div class="account-form__field">
- <input type="password" id="user-pw-repeat" class="input" autocomplete="new-password" />
- </div>
-
- </div>
-
- <div class="account-form__actions">
- <button type="button" class="btn btn-primary" id="btn-user-save">Sichern</button>
- <a href="{{ path('account_index', {tab: 'user'}) }}" class="btn btn-secondary">Abbrechen</a>
- </div>
-
- </div>
-
- {% endif %}
-
- </div>
- </div>
-
- </div>
-
- <div class="account-toast" id="account-toast"></div>
-
- <script>
- (function () {
- const toast = document.getElementById('account-toast');
-
- function showToast(msg, isError = false) {
- toast.textContent = msg;
- toast.classList.toggle('account-toast--error', isError);
- toast.classList.add('account-toast--visible');
- setTimeout(() => toast.classList.remove('account-toast--visible'), 3000);
- }
-
- async function patchJson(url, data) {
- const res = await fetch(url, {
- method: 'PATCH',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- });
- const json = await res.json();
- if (!res.ok) throw new Error(json.error ?? 'Fehler');
- return json;
- }
-
- // ── Account-Formular ──────────────────────────────────────────────────────
- const btnAccountSave = document.getElementById('btn-account-save');
- if (btnAccountSave) {
- btnAccountSave.addEventListener('click', async () => {
- try {
- await patchJson('/api/account', {
- name: document.getElementById('account-name').value.trim(),
- trackingInterval: parseInt(document.getElementById('account-interval').value, 10),
- });
- showToast('Gespeichert.');
- } catch (e) {
- showToast(e.message, true);
- }
- });
- }
-
- // ── Passwort-Toggle ───────────────────────────────────────────────────────
- const btnPwToggle = document.getElementById('btn-pw-toggle');
- const pwSection = document.getElementById('pw-section');
- if (btnPwToggle && pwSection) {
- btnPwToggle.addEventListener('click', (e) => {
- e.preventDefault();
- const open = !pwSection.hidden;
- pwSection.hidden = open;
- btnPwToggle.textContent = open ? 'ändern' : 'abbrechen';
- });
- }
-
- // ── Benutzer-Formular ────────────────────────────────────────────────────
- const btnUserSave = document.getElementById('btn-user-save');
- if (btnUserSave) {
- btnUserSave.addEventListener('click', async () => {
- const data = {
- firstName: document.getElementById('user-firstname').value.trim(),
- lastName: document.getElementById('user-lastname').value.trim(),
- email: document.getElementById('user-email').value.trim(),
- };
-
- if (pwSection && !pwSection.hidden) {
- const pwNew = document.getElementById('user-pw-new').value;
- const pwRepeat = document.getElementById('user-pw-repeat').value;
- if (pwNew !== pwRepeat) {
- showToast('Die Passwörter stimmen nicht überein.', true);
- return;
- }
- data.currentPassword = document.getElementById('user-pw-current').value;
- data.newPassword = pwNew;
- }
-
- try {
- await patchJson('/api/account/user', data);
- showToast('Gespeichert.');
- if (pwSection) {
- pwSection.hidden = true;
- document.getElementById('btn-pw-toggle').textContent = 'ändern';
- ['user-pw-current', 'user-pw-new', 'user-pw-repeat'].forEach(id => {
- document.getElementById(id).value = '';
- });
- }
- } catch (e) {
- showToast(e.message, true);
- }
- });
- }
- })();
- </script>
-
- {% endblock %}
|