diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index bbfc595..4ee88f1 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -3,7 +3,6 @@ import Header from "./lib/components/header/Header.svelte" import Footer from "./lib/components/Footer.svelte" import Notifications from "./lib/components/widgets/Notifications.svelte" - import SSRSkip from "./lib/components/SSRSkip.svelte" import { isMobile, location, openModal } from "./lib/store" import StaticHomepage from "./routes/StaticHomepage.svelte" @@ -81,6 +80,16 @@ {/if} +
+
+
+ +
+
+ + + diff --git a/frontend/src/lib/components/chatbotDemo/InputRow.svelte b/frontend/src/lib/components/chatbotDemo/InputRow.svelte new file mode 100644 index 0000000..41d3569 --- /dev/null +++ b/frontend/src/lib/components/chatbotDemo/InputRow.svelte @@ -0,0 +1,84 @@ + + +
+ + +
+ + diff --git a/frontend/src/lib/components/chatbotDemo/MessageSuggestions.svelte b/frontend/src/lib/components/chatbotDemo/MessageSuggestions.svelte new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/lib/components/chatbotDemo/Messages.svelte b/frontend/src/lib/components/chatbotDemo/Messages.svelte new file mode 100644 index 0000000..b12b417 --- /dev/null +++ b/frontend/src/lib/components/chatbotDemo/Messages.svelte @@ -0,0 +1,23 @@ + + +
+ {#each chat.messages as message, idx (idx)} +
+ {@html message.content} +
+ {/each} +
+ + diff --git a/frontend/src/lib/components/chatbotDemo/chat.ts b/frontend/src/lib/components/chatbotDemo/chat.ts new file mode 100644 index 0000000..79f61c8 --- /dev/null +++ b/frontend/src/lib/components/chatbotDemo/chat.ts @@ -0,0 +1,175 @@ +import { fetchEventSource } from "@microsoft/fetch-event-source" + +export type Role = "user" | "assistant" | "system" + +export interface ChatMessage { + role: Role + content: string +} + +export interface ChatRequestPayload { + user_id: string + message: string + session_id: string +} + +type ServerEvent = + | { type: "token"; delta: string } + | { type: "heartbeat" } + | { type: "error"; message: string } + | { type: "final"; state: unknown } + +// Optionale Konfiguration für Headers, URL usw. +export interface ChatOptions { + /** Vollständige URL, z. B. "https://api.example.com/stream" */ + url: string + /** Zusätzliche Request-Header (z. B. Auth) */ + headers?: Record + /** Fallback-Assistant-Fehlermeldung für die UI */ + fallbackErrorText?: string + /** Offen lassen, wenn Tab im Hintergrund – sinnvoll für Safari */ + openWhenHidden?: boolean + /** User-ID, wenn du sie nicht pro Aufruf übergibst */ + userId?: string +} + +export class Chat { + public messages: ChatMessage[] = [] + public isStreaming = false + public lastFinalState: unknown = null + + private sessionId: string + private opts: ChatOptions + private controller: AbortController | null = null + + constructor(sessionId: string, opts: ChatOptions) { + if (!sessionId) throw new Error("session_id ist erforderlich") + if (!opts?.url) throw new Error("ChatOptions.url ist erforderlich") + this.sessionId = sessionId + this.opts = { + fallbackErrorText: "Es ist ein Fehler aufgetreten.", + openWhenHidden: true, + ...opts, + } + } + + public abortActiveStream() { + this.controller?.abort() + this.controller = null + this.isStreaming = false + } + + /** + * Sendet eine Benutzer-Nachricht und streamt die Assistent-Antwort in `messages`. + * @param message Text der Benutzer-Nachricht + * @param userId optionaler Override der User-ID (falls nicht in opts.userId) + */ + public async generateResponse(message: string, userId?: string): Promise { + const text = (message ?? "").trim() + if (!text) return + if (this.isStreaming) this.abortActiveStream() + this.messages = [...this.messages, { role: "user", content: text }] + const assistantIndex = this.messages.length + this.messages = [...this.messages, { role: "assistant", content: "" }] + + const payload: ChatRequestPayload = { + user_id: userId ?? this.opts.userId ?? "anonymous", + message: text, + session_id: this.sessionId, + } + + this.controller = new AbortController() + this.isStreaming = true + this.lastFinalState = null + + try { + await fetchEventSource(this.opts.url, { + method: "POST", + headers: { + "Content-Type": "application/json", + ...(this.opts.headers ?? {}), + }, + body: JSON.stringify(payload), + signal: this.controller.signal, + openWhenHidden: this.opts.openWhenHidden, + + onopen: async (res) => { + if (!res.ok) throw new Error(`HTTP ${res.status}`) + }, + + onmessage: (ev) => { + if (!ev.data) return + let parsed: ServerEvent | null = null + try { + parsed = JSON.parse(ev.data) as ServerEvent + } catch { + return + } + + switch (parsed.type) { + case "token": { + const delta = parsed.delta ?? "" + const updated = { + ...this.messages[assistantIndex], + content: (this.messages[assistantIndex]?.content ?? "") + delta, + } + this.messages = [ + ...this.messages.slice(0, assistantIndex), + updated, + ...this.messages.slice(assistantIndex + 1), + ] + break + } + + case "heartbeat": { + break + } + + case "error": { + const msg = parsed.message || this.opts.fallbackErrorText! + const updated = { + ...this.messages[assistantIndex], + content: (this.messages[assistantIndex]?.content || "") + `\n\n⚠️ ${msg}`, + } + this.messages = [ + ...this.messages.slice(0, assistantIndex), + updated, + ...this.messages.slice(assistantIndex + 1), + ] + this.abortActiveStream() + break + } + + case "final": { + this.lastFinalState = parsed.state + this.abortActiveStream() + break + } + + default: { + break + } + } + }, + + onerror: (err) => { + const updated = { + ...this.messages[assistantIndex], + content: + (this.messages[assistantIndex]?.content || "") + + `\n\n⚠️ ${this.opts.fallbackErrorText} (${String(err)})`, + } + this.messages = [ + ...this.messages.slice(0, assistantIndex), + updated, + ...this.messages.slice(assistantIndex + 1), + ] + throw err + }, + }) + } finally { + this.isStreaming = false + this.controller = null + } + } +} diff --git a/frontend/src/lib/components/pagebuilder/Breadcrumbs.svelte b/frontend/src/lib/components/pagebuilder/Breadcrumbs.svelte deleted file mode 100644 index 3f61ce8..0000000 --- a/frontend/src/lib/components/pagebuilder/Breadcrumbs.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - - -{#if paths.length} - -{/if} diff --git a/frontend/src/lib/components/pagebuilder/ContentBlock.svelte b/frontend/src/lib/components/pagebuilder/ContentBlock.svelte deleted file mode 100644 index c90efb7..0000000 --- a/frontend/src/lib/components/pagebuilder/ContentBlock.svelte +++ /dev/null @@ -1,301 +0,0 @@ - - - - {#if block.anchorId} - -
-
-
- {/if} -
- {#if block.background?.image} -
-
- - {#if block?.background?.overlay} -
- {/if} -
-
- {/if} -
-
- {#if block.headline || block.subline} -
-
- - {#if block.headline} - {#if block.headlineH1} -

{block.headline}

- {:else} -

{block.headline}

- {/if} - {/if} - {#if block.subline} -

{block.subline}

- {/if} -
- {#if block?.headlineLink} - - {/if} -
- {/if} - - -
- {#each block.callToActionButtons || [] as button} -
-
-
-
-
- - diff --git a/frontend/src/lib/components/pagebuilder/DefaultImage.svelte b/frontend/src/lib/components/pagebuilder/DefaultImage.svelte deleted file mode 100644 index c67a993..0000000 --- a/frontend/src/lib/components/pagebuilder/DefaultImage.svelte +++ /dev/null @@ -1,126 +0,0 @@ - - -{#if images.length > 1} -
- - {#each images as image (image)} - -
- -
-
- {/each} -
-
-{:else if images[0]} -
- -
-{/if} - - diff --git a/frontend/src/lib/components/pagebuilder/Loader.svelte b/frontend/src/lib/components/pagebuilder/Loader.svelte deleted file mode 100644 index 81cd48c..0000000 --- a/frontend/src/lib/components/pagebuilder/Loader.svelte +++ /dev/null @@ -1,36 +0,0 @@ - - -
- {#if type == "bar"} - - {:else} - - {/if} -
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/ChapterPreview.svelte b/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/ChapterPreview.svelte deleted file mode 100644 index ea31896..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/ChapterPreview.svelte +++ /dev/null @@ -1,105 +0,0 @@ - - -
-
    - {#each $selfImprovementChapters as chapter, i} -
  • - -
  • - {/each} -
-
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/Item.svelte b/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/Item.svelte deleted file mode 100644 index bdcd610..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/ChapterPreview/Item.svelte +++ /dev/null @@ -1,350 +0,0 @@ - - -
- {#if chapter.locked} -
- - - -

Coming Soon

-
- {/if} -
- - -
-
-
-
-
-
-
-

- {chapter.alias} -

-

- {chapter.title} -

-

- {chapter.shortDescription} -

-
-
- -
-
-
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/Columns.svelte b/frontend/src/lib/components/pagebuilder/blocks/Columns.svelte deleted file mode 100644 index 1bd88a1..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/Columns.svelte +++ /dev/null @@ -1,30 +0,0 @@ - - -
- {#each block.columns || [] as column} - - {/each} -
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/ColumnsColumn.svelte b/frontend/src/lib/components/pagebuilder/blocks/ColumnsColumn.svelte deleted file mode 100644 index 4800fa8..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/ColumnsColumn.svelte +++ /dev/null @@ -1,72 +0,0 @@ - - -
- {#if column.type == "text"} - - {:else if column.type == "image"} - - {:else if column.type == "cta"} - - {:else if column.type == "chapterDescription"} - - {/if} -
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/GoogleMaps.svelte b/frontend/src/lib/components/pagebuilder/blocks/GoogleMaps.svelte deleted file mode 100644 index 4146be8..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/GoogleMaps.svelte +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/HomepageRow.svelte b/frontend/src/lib/components/pagebuilder/blocks/HomepageRow.svelte deleted file mode 100644 index 39ae879..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/HomepageRow.svelte +++ /dev/null @@ -1,92 +0,0 @@ - - -
-
-
- -
-
- -
-
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/ImproveYourselfDescription.svelte b/frontend/src/lib/components/pagebuilder/blocks/ImproveYourselfDescription.svelte deleted file mode 100644 index b331764..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/ImproveYourselfDescription.svelte +++ /dev/null @@ -1,184 +0,0 @@ - - -
-
- -
-
-
-

Improve Yourself

-

{@html des.upperDescription}

-
    -
  • - - - - - Fitness -
  • -
  • - - - - - Entspannung -
  • -
  • - - - - - Ernährung -
  • -
  • - - - - - Weiterbildung -
  • -
-

{@html des.lowerDescription}

-
-
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/NewsletterRow.svelte b/frontend/src/lib/components/pagebuilder/blocks/NewsletterRow.svelte deleted file mode 100644 index e946999..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/NewsletterRow.svelte +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/PredefinedBlock.svelte b/frontend/src/lib/components/pagebuilder/blocks/PredefinedBlock.svelte deleted file mode 100644 index 27602ea..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/PredefinedBlock.svelte +++ /dev/null @@ -1,12 +0,0 @@ - - -{#if block.predefinedBlock?.id} - -{/if} diff --git a/frontend/src/lib/components/pagebuilder/blocks/RatingPreview/PreviewCard.svelte b/frontend/src/lib/components/pagebuilder/blocks/RatingPreview/PreviewCard.svelte deleted file mode 100644 index 0b57eca..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/RatingPreview/PreviewCard.svelte +++ /dev/null @@ -1,261 +0,0 @@ - - - - -{#if ratings.length} -
-
    - {#each ratings as rating} -
  • -
    - - - -
    - {rating.title} - -
    -
    -

    - {rating.title} -

    -

    {rating.comment}

    -
    {formatDate(rating.review_date)}
    -
    -
    -
    -
    -
    - - - - {returnAvgForRating(rating)} -
    -
    -
    -
  • - {/each} -
-
-{/if} - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/SplittedHomepage.svelte b/frontend/src/lib/components/pagebuilder/blocks/SplittedHomepage.svelte deleted file mode 100644 index 185e741..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/SplittedHomepage.svelte +++ /dev/null @@ -1,203 +0,0 @@ - - -
-
-
    - {#each selfImprovementChapters as chapter, i} -
  • - {#if i == selectedChapter} -

    - {chapter.title} -

    - {:else} -

    {chapter.alias}

    - {/if} - -

    - {@html chapter.shortDescription} -

    -
  • - {/each} -
-
- - - - - - - - -
-
- - diff --git a/frontend/src/lib/components/pagebuilder/blocks/Step.svelte b/frontend/src/lib/components/pagebuilder/blocks/Step.svelte deleted file mode 100644 index 09a91bc..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/Step.svelte +++ /dev/null @@ -1,48 +0,0 @@ - - -
  • -
    - -

    - {i + 1} -

    -
    -
    -
    -

    - {item.title} -

    - - - - -
    -
    -
      - {#each item.descriptions as description} -
    • - {description} -
    • - {/each} -
    -
    -
    -
  • diff --git a/frontend/src/lib/components/pagebuilder/blocks/Steps.svelte b/frontend/src/lib/components/pagebuilder/blocks/Steps.svelte deleted file mode 100644 index 591c327..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/Steps.svelte +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - -{#if block.steps?.horizontal} -
    -
      - {#each block.steps.items as item, i} - - {/each} -
    -
    -{:else} -
      - {#each block.steps.items as item, i} - - {/each} -
    -{/if} - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/columns/CTA.svelte b/frontend/src/lib/components/pagebuilder/blocks/columns/CTA.svelte deleted file mode 100644 index fa610a7..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/columns/CTA.svelte +++ /dev/null @@ -1,52 +0,0 @@ - - -
    - {#if cta.upperHeadline} - - {cta.upperHeadline} - - {/if} - -

    - {cta.whiteHeadline} - {#if cta.headlineArrangement !== "row"}
    {/if} {cta.redHeadline} -

    - -

    {cta.description}

    -
    - {#each cta.callToActionButtons as button} -
    -
    - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/columns/ChapterDescription.svelte b/frontend/src/lib/components/pagebuilder/blocks/columns/ChapterDescription.svelte deleted file mode 100644 index 2a8f56c..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/columns/ChapterDescription.svelte +++ /dev/null @@ -1,27 +0,0 @@ - - -
    -

    - {title} -

    -

    - {@html description} -

    -
    - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/columns/Text.svelte b/frontend/src/lib/components/pagebuilder/blocks/columns/Text.svelte deleted file mode 100644 index 719ba0b..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/columns/Text.svelte +++ /dev/null @@ -1,13 +0,0 @@ - - -{@html column.text} -{#if column.links?.length} -
    - - -
    -{/if} diff --git a/frontend/src/lib/components/pagebuilder/blocks/form/Calendar.svelte b/frontend/src/lib/components/pagebuilder/blocks/form/Calendar.svelte deleted file mode 100644 index 43cc2b3..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/form/Calendar.svelte +++ /dev/null @@ -1,193 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/form/FileInput.svelte b/frontend/src/lib/components/pagebuilder/blocks/form/FileInput.svelte deleted file mode 100644 index 0d66a7a..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/form/FileInput.svelte +++ /dev/null @@ -1,342 +0,0 @@ - - - -{#if showApproveModal} - - Dateiformat Warnung -

    - Deine Datei wird von einigen Browsern, insbesondere von Google Chrome, nur eingeschränkt unterstützt. Wenn - du die Datei dennoch hochladen möchtest, klicke auf "Fortfahren". Andernfalls empfehlen wir, das Video - zunächst in eine MP4-Datei zu konvertieren. Dafür stehen zahlreiche kostenlose Online-Dienste zur Verfügung. -

    - -
    -{/if} - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/form/Input.svelte b/frontend/src/lib/components/pagebuilder/blocks/form/Input.svelte deleted file mode 100644 index 0869632..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/form/Input.svelte +++ /dev/null @@ -1,143 +0,0 @@ - - - - - diff --git a/frontend/src/lib/components/pagebuilder/blocks/form/Select.svelte b/frontend/src/lib/components/pagebuilder/blocks/form/Select.svelte deleted file mode 100644 index 05d8381..0000000 --- a/frontend/src/lib/components/pagebuilder/blocks/form/Select.svelte +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - -