Projekte anlegen und ein leerer Zustand, der fuehrt statt zu enttaeuschen
Rueckmeldung 22.08.2026 mit Bildschirmfoto aus dem eigenen Testzugang: "die seite soll jetzt schon bitte richtig krass sein und hoch profissionel, auch sehr detailliert." Zwei Luecken, beide geschlossen: 1) Projekte liessen sich nur ueber die Schnittstelle anlegen. Jetzt in der Verwaltung: pro Kunde ein "+ Projekt" mit Titel, Paket, Preis, Richttermin und naechstem Schritt. Bewusst als Einblendung direkt bei der Kundenzeile statt als eigene Seite -- man legt ein Projekt IMMER fuer einen bestimmten Kunden an, nie im luftleeren Raum. Der Kundenname steht deshalb gross im Formular, damit es nicht versehentlich dem Falschen angehaengt wird. Die 30 % Anzahlung wird beim Tippen live mitgerechnet. Sie wird zwar serverseitig berechnet, aber wer sie beim Eintippen sieht, merkt eine falsche Null sofort -- und nicht erst, wenn der Kunde ueberweisen soll. 2) Der leere Zustand im Portal war ein einziger Satz. Das ist eine verpasste Gelegenheit: Wer dort zum ersten Mal landet, hat gerade sein Passwort gesetzt und weiss noch nicht, was ihn erwartet -- genau dann entscheidet sich, ob die Seite souveraen wirkt oder unfertig. Jetzt zeigt er in vier Punkten, WAS gleich hier stehen wird (Projektstand, wer am Zug ist, Dateien und Nachrichten, Ideen jederzeit) und schliesst mit der Zusicherung, dass nichts zu tun ist. Fuenfsprachig. 45/45 Handy-Abnahme, i18n vollstaendig. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -707,6 +707,8 @@
|
||||
(k.letzter_login ? "zuletzt " + window.WD.datum(k.letzter_login) : "noch nie angemeldet") +
|
||||
"</span>" +
|
||||
'<span style="display:block;margin-top:.5rem">' +
|
||||
'<button type="button" class="wd-btn wd-btn--zweit wd-btn--klein" data-projekt-fuer="' + s(k.id) +
|
||||
'" data-projekt-name="' + s(k.name) + '">+ Projekt</button> ' +
|
||||
'<button type="button" class="wd-btn wd-btn--still wd-btn--klein" data-neuer-link="' + s(k.id) + '">Neuer Link</button> ' +
|
||||
'<button type="button" class="wd-btn wd-btn--still wd-btn--klein" data-schalten="' + s(k.id) +
|
||||
'" data-frei="' + (k.freigeschaltet ? "0" : "1") + '">' +
|
||||
@@ -715,6 +717,12 @@
|
||||
"</span></div>";
|
||||
}).join("");
|
||||
|
||||
ziel.querySelectorAll("[data-projekt-fuer]").forEach(function (b) {
|
||||
b.addEventListener("click", function () {
|
||||
zeigeProjektFormular(b.dataset.projektFuer, b.dataset.projektName);
|
||||
});
|
||||
});
|
||||
|
||||
ziel.querySelectorAll("[data-neuer-link]").forEach(function (b) {
|
||||
b.addEventListener("click", async function () {
|
||||
window.WD.knopfSperren(b, true, "…");
|
||||
@@ -828,6 +836,111 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
PROJEKT ANLEGEN
|
||||
|
||||
Bewusst als Einblendung direkt bei der Kundenzeile statt als eigene
|
||||
Seite: man legt ein Projekt IMMER fuer einen bestimmten Kunden an,
|
||||
nie im luftleeren Raum. Der Kundenname steht deshalb gross im
|
||||
Formular -- so kann man es nicht versehentlich dem Falschen anhaengen.
|
||||
----------------------------------------------------------------- */
|
||||
function zeigeProjektFormular(kundeId, kundeName) {
|
||||
var box = document.getElementById("vw-link-box");
|
||||
box.hidden = false;
|
||||
box.innerHTML =
|
||||
'<div class="wd-karte" style="cursor:default;display:block">' +
|
||||
'<h3 style="margin:0 0 .2rem">Neues Projekt</h3>' +
|
||||
'<p class="wd-klein" style="color:var(--wd-blau);margin:0 0 1rem">für ' + s(kundeName) + '</p>' +
|
||||
'<div class="wd-grid wd-grid--2">' +
|
||||
'<div class="wd-feld" id="vw-feld-ptitel">' +
|
||||
'<label for="vw-ptitel">Projekttitel<span class="wd-pflicht">*</span></label>' +
|
||||
'<input type="text" id="vw-ptitel" placeholder="z. B. Website Handwerksbetrieb Meier" />' +
|
||||
'<p class="wd-feld-fehler"></p>' +
|
||||
'</div>' +
|
||||
'<div class="wd-feld">' +
|
||||
'<label for="vw-ppaket">Paket</label>' +
|
||||
'<select id="vw-ppaket">' +
|
||||
'<option value="onepager">Onepager — ab 300 €</option>' +
|
||||
'<option value="website" selected>Professionelle Website — ab 500 €</option>' +
|
||||
'<option value="shop">Shop & umfangreiche Website — ab 1.000 €</option>' +
|
||||
'<option value="verwaltung">Buchhaltungs- & Steuerverwaltung — ab 1.500 €</option>' +
|
||||
'<option value="betreuung">Laufende Betreuung — ab 49 €/Monat</option>' +
|
||||
'</select>' +
|
||||
'</div>' +
|
||||
'<div class="wd-feld">' +
|
||||
'<label for="vw-ppreis">Gesamtpreis in Euro</label>' +
|
||||
'<input type="number" id="vw-ppreis" min="0" step="1" placeholder="1500" inputmode="numeric" />' +
|
||||
'<span class="wd-feld-hilfe" id="vw-panzahlung">Die 30 % Anzahlung wird daraus automatisch berechnet.</span>' +
|
||||
'</div>' +
|
||||
'<div class="wd-feld">' +
|
||||
'<label for="vw-ptermin">Richttermin <span class="wd-leise">optional</span></label>' +
|
||||
'<input type="text" id="vw-ptermin" placeholder="z. B. Mitte Oktober" />' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="wd-feld">' +
|
||||
'<label for="vw-pschritt">Nächster Schritt <span class="wd-leise">sieht der Kunde sofort</span></label>' +
|
||||
'<input type="text" id="vw-pschritt" placeholder="z. B. Briefing-Termin vereinbaren" />' +
|
||||
'</div>' +
|
||||
'<div class="wd-btn-reihe">' +
|
||||
'<button type="button" class="wd-btn wd-btn--haupt" id="vw-projekt-speichern">Projekt anlegen</button>' +
|
||||
'<button type="button" class="wd-btn wd-btn--still" id="vw-projekt-abbrechen">Abbrechen</button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
box.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
setTimeout(function () { document.getElementById("vw-ptitel").focus(); }, 100);
|
||||
|
||||
/* Die Anzahlung live mitrechnen. Sie wird zwar serverseitig berechnet,
|
||||
aber wer sie beim Eintippen sieht, merkt eine falsche Null sofort --
|
||||
und nicht erst, wenn der Kunde den Betrag ueberweisen soll. */
|
||||
var preisFeld = document.getElementById("vw-ppreis");
|
||||
preisFeld.addEventListener("input", function () {
|
||||
var wert = Number(preisFeld.value);
|
||||
document.getElementById("vw-panzahlung").textContent =
|
||||
Number.isFinite(wert) && wert > 0
|
||||
? "30 % Anzahlung: " + (Math.round(wert * 100 * 0.3) / 100).toFixed(2).replace(".", ",") + " €"
|
||||
: "Die 30 % Anzahlung wird daraus automatisch berechnet.";
|
||||
});
|
||||
|
||||
document.getElementById("vw-projekt-abbrechen").addEventListener("click", function () {
|
||||
box.hidden = true; box.innerHTML = "";
|
||||
});
|
||||
|
||||
document.getElementById("vw-projekt-speichern").addEventListener("click", async function (e) {
|
||||
var titel = document.getElementById("vw-ptitel").value.trim();
|
||||
var feld = document.getElementById("vw-feld-ptitel");
|
||||
feld.classList.remove("wd-feld--fehler");
|
||||
if (!titel) {
|
||||
feld.classList.add("wd-feld--fehler");
|
||||
feld.querySelector(".wd-feld-fehler").textContent = "Bitte einen Projekttitel angeben.";
|
||||
return;
|
||||
}
|
||||
window.WD.knopfSperren(e.target, true, "Wird angelegt…");
|
||||
try {
|
||||
var r = await api("/webdesign/admin/projekte", {
|
||||
method: "POST",
|
||||
body: {
|
||||
kundeId: kundeId,
|
||||
titel: titel,
|
||||
paket: document.getElementById("vw-ppaket").value,
|
||||
preisEuro: Number(document.getElementById("vw-ppreis").value) || undefined,
|
||||
richttermin: document.getElementById("vw-ptermin").value.trim(),
|
||||
naechsterSchritt: document.getElementById("vw-pschritt").value.trim(),
|
||||
},
|
||||
});
|
||||
box.innerHTML = '<div class="vw-link-anzeige">' +
|
||||
'<p class="wd-hinweis-titel">Projekt ' + s(r.nummer) + ' angelegt</p>' +
|
||||
'<p class="wd-klein" style="margin:0">' +
|
||||
(r.anzahlungText ? "Anzahlung 30 %: <strong>" + s(r.anzahlungText) + "</strong>. " : "") +
|
||||
'Der Kunde sieht es ab sofort in seinem Projektraum.</p></div>';
|
||||
ladeKunden();
|
||||
} catch (f) {
|
||||
window.WD.knopfSperren(e.target, false);
|
||||
window.WD.meldung(meldung, f.message, "fehler");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------------- Start ----------------
|
||||
|
||||
Reihenfolge bewusst so:
|
||||
|
||||
Reference in New Issue
Block a user