implementation for the warenkorb system
This commit is contained in:
@@ -416,6 +416,7 @@
|
||||
const form = document.getElementById('checkout-form');
|
||||
const errorAlert = document.getElementById('form-error-alert');
|
||||
const statusText = document.getElementById('loading-status-text');
|
||||
const spinner = document.querySelector('.spinner'); // Referenz auf den Ladekreis
|
||||
|
||||
// Subdomain Live-Prüfung
|
||||
const slugInput = document.getElementById('tenant_slug');
|
||||
@@ -423,17 +424,23 @@
|
||||
const submitBtn = document.getElementById('booking_submit');
|
||||
let slugTimer = null;
|
||||
|
||||
// OPTIMIERT: Alles im 'input'-Event (fängt auch Maus-Paste und Autocomplete)
|
||||
slugInput.addEventListener('input', (e) => {
|
||||
// 1. Sanitization
|
||||
e.target.value = e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
||||
});
|
||||
|
||||
slugInput.addEventListener('keyup', (e) => {
|
||||
|
||||
// 2. Debounced API Check
|
||||
clearTimeout(slugTimer);
|
||||
slugTimer = setTimeout(() => checkSubdomain(e.target.value), 600);
|
||||
});
|
||||
|
||||
async function checkSubdomain(name) {
|
||||
if (name.length < 3) return;
|
||||
if (name.length < 3) {
|
||||
feedback.textContent = 'Bitte mindestens 3 Zeichen eingeben.';
|
||||
feedback.style.color = '#5e757d';
|
||||
submitBtn.disabled = true;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await fetch(`/instance_request/check_subdomain?slug=${name}`);
|
||||
const j = await res.json();
|
||||
@@ -448,6 +455,8 @@
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
feedback.textContent = 'Prüfung fehlgeschlagen. Bitte erneut versuchen.';
|
||||
feedback.style.color = '#b02a37';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -457,7 +466,11 @@
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
errorAlert.style.display = 'none';
|
||||
|
||||
// OPTIMIERT: Visuelles Feedback für den initialen Submit
|
||||
const originalBtnText = submitBtn.textContent;
|
||||
submitBtn.disabled = true;
|
||||
submitBtn.textContent = "Wird verarbeitet...";
|
||||
|
||||
const formData = new FormData(form);
|
||||
const tenantSlug = formData.get('tenant_slug');
|
||||
@@ -486,6 +499,7 @@
|
||||
errorAlert.textContent = error.message;
|
||||
errorAlert.style.display = 'block';
|
||||
submitBtn.disabled = false;
|
||||
submitBtn.textContent = originalBtnText; // Button zurücksetzen
|
||||
}
|
||||
});
|
||||
|
||||
@@ -509,9 +523,22 @@
|
||||
}
|
||||
}, 3500);
|
||||
|
||||
let retryCount = 0;
|
||||
const maxRetries = 30; // OPTIMIERT: Max 90 Sekunden Polling (30 * 3s)
|
||||
|
||||
const checkStatus = async () => {
|
||||
retryCount++;
|
||||
|
||||
// Timeout-Abbruch
|
||||
if (retryCount > maxRetries) {
|
||||
handlePollingError("Zeitüberschreitung. Die Bereitstellung dauert ungewöhnlich lange. Sie werden per E-Mail informiert, sobald das System bereit ist.", msgInterval);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const res = await fetch(`/instance_request/status?slug=${slug}`);
|
||||
if (!res.ok) throw new Error("Network response was not ok");
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (data.status === 'ready') {
|
||||
@@ -520,14 +547,13 @@
|
||||
showSuccessState(data.url, data.username, data.password, data.invoice_url);
|
||||
} else if (data.status === 'failed') {
|
||||
// SETUP FEHLGESCHLAGEN
|
||||
clearInterval(msgInterval);
|
||||
statusText.textContent = "Fehler bei der Bereitstellung. Bitte Support kontaktieren.";
|
||||
statusText.style.color = '#b02a37';
|
||||
handlePollingError("Fehler bei der Bereitstellung. Bitte kontaktieren Sie unseren Support.", msgInterval);
|
||||
} else {
|
||||
// SETUP LÄUFT NOCH -> in 3 Sekunden erneut prüfen
|
||||
setTimeout(checkStatus, 3000);
|
||||
}
|
||||
} catch (err) {
|
||||
// Bei Netzwerkfehler weiter versuchen, solange maxRetries nicht erreicht ist
|
||||
setTimeout(checkStatus, 3000);
|
||||
}
|
||||
};
|
||||
@@ -535,6 +561,17 @@
|
||||
// Starte den ersten Check nach 2 Sekunden
|
||||
setTimeout(checkStatus, 2000);
|
||||
}
|
||||
|
||||
// OPTIMIERT: Hilfsfunktion für Polling-Fehler (verhindert Sackgassen-UI)
|
||||
function handlePollingError(message, intervalId) {
|
||||
clearInterval(intervalId);
|
||||
statusText.textContent = message;
|
||||
statusText.style.color = '#b02a37';
|
||||
if (spinner) spinner.style.display = 'none'; // Spinner ausblenden
|
||||
|
||||
// Optional: Einen Zurück/Support-Button einfügen
|
||||
statusText.insertAdjacentHTML('afterend', '<br><a href="#" onclick="window.location.reload(); return false;" class="btn secondary" style="margin-top:1rem;">Seite neu laden</a>');
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// Erfolgs-Bildschirm anzeigen
|
||||
|
||||
Reference in New Issue
Block a user