Phase 6: KI-Prompt-Generator

Neues Modul js/ai/promptBuilder.js: reine Funktion buildPrompt(), deckt
alle 10 Pflichtpunkte aus anforderung.md explizit ab (Region+Radius,
Kategorien, Alter, wichtige Eigenschaften, Anzahl Ergebnisse, keine
erfundenen Informationen, unsichere Angaben kennzeichnen, ausschliesslich
gueltiges JSON, genaue Koordinaten, direkte Importierbarkeit) und bettet
das exakte JSON-Zielschema aus anforderung.md unveraendert ein.

UI (js/ui/promptGenerator.js): Modal mit allen Eingabefeldern aus der
Anforderung (Region, Radius, Kategorien, Altersgruppe, Indoor/Outdoor,
Kostenrahmen, max. Ergebnisse, besondere Anforderungen als Checkboxen +
Freitext, Ausgabesprache), Live-Vorschau des generierten Prompts,
Copy-to-Clipboard mit execCommand-Fallback (js/utils/clipboard.js) und
Speichern als Textdatei (js/utils/download.js). Neuer Toolbar-Button
oeffnet den Generator.

JSON-Import der KI-Antwort ist bewusst nicht Teil dieser Phase, sondern
folgt in Phase 7. docs/plan.md entsprechend fortgeschrieben.
This commit is contained in:
2026-07-24 12:32:37 +02:00
parent dac952fbf9
commit 5e2197ec24
9 changed files with 963 additions and 2 deletions
+52
View File
@@ -0,0 +1,52 @@
// Zwischenablage-Utility für den KI-Prompt-Generator (Phase 6). Nutzt primär
// die moderne Clipboard API, fällt aber auf das ältere
// document.execCommand('copy') zurück, falls navigator.clipboard nicht
// verfügbar ist oder der Aufruf fehlschlägt (z.B. weil manche Browser die
// Clipboard API unter file:// einschränken).
(function () {
/** Kopiert per unsichtbarem <textarea> + execCommand('copy'). Gibt boolean zurück. */
function copyViaExecCommand(text) {
const textarea = document.createElement('textarea');
textarea.value = text;
// Unsichtbar, aber im Layout-Fluss vorhanden, damit select() zuverlässig funktioniert.
textarea.style.position = 'fixed';
textarea.style.top = '-1000px';
textarea.style.left = '-1000px';
textarea.setAttribute('readonly', '');
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
let success = false;
try {
success = document.execCommand('copy');
} catch (err) {
success = false;
}
document.body.removeChild(textarea);
return success;
}
/**
* Kopiert einen Text in die Zwischenablage.
* @param {string} text
* @returns {Promise<boolean>} true, wenn das Kopieren erfolgreich war.
*/
async function copyToClipboard(text) {
if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
// Fällt unten auf den execCommand-Fallback zurück (z.B. Berechtigung
// verweigert oder API unter file:// eingeschränkt).
}
}
return copyViaExecCommand(text);
}
EventMap.utils.copyToClipboard = copyToClipboard;
})();
+1
View File
@@ -16,6 +16,7 @@ window.EventMap.store = window.EventMap.store || {};
window.EventMap.map = window.EventMap.map || {};
window.EventMap.ui = window.EventMap.ui || {};
window.EventMap.filters = window.EventMap.filters || {};
window.EventMap.ai = window.EventMap.ai || {};
(function () {
/**
+30
View File
@@ -0,0 +1,30 @@
// Download-Utility für den KI-Prompt-Generator (Phase 6): erzeugt clientseitig
// einen Blob und triggert den Download über ein unsichtbares
// <a download>-Element. Funktioniert rein clientseitig, also auch unter
// file:// ohne lokalen Server.
(function () {
/**
* Speichert Text als Datei über den Browser-Download.
* @param {string} filename
* @param {string} content
*/
function downloadTextFile(filename, content) {
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
link.style.display = 'none';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
// URL erst leicht verzögert freigeben, damit der Download-Vorgang
// in jedem Browser sicher gestartet werden konnte.
setTimeout(() => URL.revokeObjectURL(url), 1000);
}
EventMap.utils.downloadTextFile = downloadTextFile;
})();