feat: BotKonzept Frontend erstellt
Neue Dateien: - index.html: Landing Page mit Registrierung - dashboard.html: Kunden-Dashboard - css/style.css: Haupt-Stylesheet (1500+ Zeilen) - css/dashboard.css: Dashboard-Styles (800+ Zeilen) - js/main.js: Landing Page JavaScript - js/dashboard.js: Dashboard JavaScript - logo/20250119_Logo_Botkozept.svg: Logo Features: - Modernes, responsives Design - Hero-Section mit Chat-Preview Animation - Feature-Übersicht und Pricing-Tabelle - Registrierungsformular mit Validierung - FAQ-Akkordeon - Dashboard mit PDF-Upload (Drag & Drop) - Chatbot-Test-Interface - Embed-Code Generator - Trial-Status und Upgrade-Banner - Mobile-optimiert
This commit is contained in:
181
README.md
181
README.md
@@ -0,0 +1,181 @@
|
||||
# BotKonzept Frontend
|
||||
|
||||
Modernes, responsives Frontend für die BotKonzept SaaS-Plattform.
|
||||
|
||||
## 📁 Projektstruktur
|
||||
|
||||
```
|
||||
customer-frontend/
|
||||
├── index.html # Landing Page mit Registrierung
|
||||
├── dashboard.html # Kunden-Dashboard
|
||||
├── css/
|
||||
│ ├── style.css # Haupt-Stylesheet
|
||||
│ └── dashboard.css # Dashboard-spezifische Styles
|
||||
├── js/
|
||||
│ ├── main.js # Landing Page JavaScript
|
||||
│ └── dashboard.js # Dashboard JavaScript
|
||||
└── logo/
|
||||
└── 20250119_Logo_Botkozept.svg
|
||||
```
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
### Landing Page (index.html)
|
||||
- ✅ Modernes, responsives Design
|
||||
- ✅ Hero-Section mit animiertem Chat-Preview
|
||||
- ✅ Feature-Übersicht
|
||||
- ✅ "So funktioniert's" Sektion
|
||||
- ✅ Pricing-Tabelle mit Rabatt-Timeline
|
||||
- ✅ Registrierungsformular
|
||||
- ✅ FAQ-Akkordeon
|
||||
- ✅ Mobile-optimiert
|
||||
|
||||
### Dashboard (dashboard.html)
|
||||
- ✅ Übersicht mit Statistiken
|
||||
- ✅ PDF-Upload mit Drag & Drop
|
||||
- ✅ Dokumenten-Verwaltung
|
||||
- ✅ Chatbot-Test-Interface
|
||||
- ✅ Embed-Code Generator
|
||||
- ✅ Einstellungen
|
||||
- ✅ Trial-Status & Upgrade-Banner
|
||||
|
||||
## 🎨 Design-System
|
||||
|
||||
### Farben
|
||||
```css
|
||||
--primary: #6366f1; /* Indigo */
|
||||
--secondary: #0ea5e9; /* Sky Blue */
|
||||
--accent: #f59e0b; /* Amber */
|
||||
--success: #10b981; /* Emerald */
|
||||
--error: #ef4444; /* Red */
|
||||
```
|
||||
|
||||
### Typografie
|
||||
- Font: Inter (Google Fonts)
|
||||
- Responsive Schriftgrößen mit `clamp()`
|
||||
|
||||
### Komponenten
|
||||
- Buttons (Primary, Outline, White)
|
||||
- Cards
|
||||
- Forms
|
||||
- Modals
|
||||
- Notifications
|
||||
|
||||
## 🔧 Konfiguration
|
||||
|
||||
### API-Endpunkte
|
||||
|
||||
In `js/main.js`:
|
||||
```javascript
|
||||
const CONFIG = {
|
||||
WEBHOOK_URL: 'https://n8n.userman.de/webhook/botkonzept-registration',
|
||||
API_BASE_URL: 'https://api.botkonzept.de',
|
||||
};
|
||||
```
|
||||
|
||||
### Webhook-Integration
|
||||
|
||||
Das Registrierungsformular sendet folgende Daten an den Webhook:
|
||||
```json
|
||||
{
|
||||
"firstName": "Max",
|
||||
"lastName": "Mustermann",
|
||||
"email": "max@beispiel.de",
|
||||
"company": "Muster GmbH",
|
||||
"website": "https://beispiel.de",
|
||||
"newsletter": true,
|
||||
"timestamp": "2025-01-25T10:00:00.000Z",
|
||||
"source": "website"
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 Responsive Breakpoints
|
||||
|
||||
- Desktop: > 1024px
|
||||
- Tablet: 768px - 1024px
|
||||
- Mobile: < 768px
|
||||
- Small Mobile: < 480px
|
||||
|
||||
## 🚀 Deployment
|
||||
|
||||
### Lokales Testen
|
||||
```bash
|
||||
cd customer-frontend
|
||||
python3 -m http.server 8000
|
||||
# Öffnen: http://localhost:8000
|
||||
```
|
||||
|
||||
### Produktion
|
||||
```bash
|
||||
# Dateien auf Webserver kopieren
|
||||
rsync -avz . user@botkonzept.de:/var/www/botkonzept/
|
||||
```
|
||||
|
||||
### NGINX Konfiguration
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name botkonzept.de www.botkonzept.de;
|
||||
|
||||
root /var/www/botkonzept;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(css|js|svg|png|jpg|jpeg|gif|ico)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 Sicherheit
|
||||
|
||||
- HTTPS erforderlich für Produktion
|
||||
- CORS-Header für API-Calls
|
||||
- Input-Validierung auf Client-Seite
|
||||
- XSS-Schutz durch HTML-Escaping
|
||||
|
||||
## 📊 Analytics
|
||||
|
||||
Google Analytics 4 Integration vorbereitet:
|
||||
```html
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
|
||||
```
|
||||
|
||||
Conversion-Tracking:
|
||||
```javascript
|
||||
trackConversion('registration_complete', { email: '...' });
|
||||
```
|
||||
|
||||
## 🎯 Customer Journey
|
||||
|
||||
1. **Besucher** kommt auf botkonzept.de
|
||||
2. **Registrierung** über Formular
|
||||
3. **Instanz-Erstellung** (automatisch via n8n Workflow)
|
||||
4. **Dashboard-Zugang** per E-Mail
|
||||
5. **PDF-Upload** in Wissensdatenbank
|
||||
6. **Embed-Code** für Website kopieren
|
||||
7. **Trial-Reminder** (Tag 3, 5, 7)
|
||||
8. **Upgrade** oder Ablauf
|
||||
|
||||
## 📝 TODO
|
||||
|
||||
- [ ] Stripe/PayPal Integration
|
||||
- [ ] E-Mail-Verifizierung
|
||||
- [ ] Passwort-Reset
|
||||
- [ ] Multi-Language Support
|
||||
- [ ] Dark Mode
|
||||
- [ ] PWA Support
|
||||
|
||||
## 📄 Lizenz
|
||||
|
||||
Proprietär - Alle Rechte vorbehalten
|
||||
|
||||
---
|
||||
|
||||
**Version:** 1.0.0
|
||||
**Erstellt:** Januar 2025
|
||||
|
||||
1128
css/dashboard.css
Normal file
1128
css/dashboard.css
Normal file
File diff suppressed because it is too large
Load Diff
1573
css/style.css
Normal file
1573
css/style.css
Normal file
File diff suppressed because it is too large
Load Diff
480
dashboard.html
Normal file
480
dashboard.html
Normal file
@@ -0,0 +1,480 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="robots" content="noindex, nofollow">
|
||||
<title>Dashboard - BotKonzept</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/svg+xml" href="logo/20250119_Logo_Botkozept.svg">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="css/dashboard.css">
|
||||
</head>
|
||||
<body class="dashboard-body">
|
||||
<!-- Dashboard Navigation -->
|
||||
<nav class="dashboard-nav">
|
||||
<div class="nav-brand">
|
||||
<a href="index.html" class="logo">
|
||||
<img src="logo/20250119_Logo_Botkozept.svg" alt="BotKonzept Logo">
|
||||
<span>BotKonzept</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-user">
|
||||
<div class="trial-badge" id="trialBadge">
|
||||
<i class="fas fa-clock"></i>
|
||||
<span>Trial: <strong id="trialDays">7</strong> Tage übrig</span>
|
||||
</div>
|
||||
<div class="user-menu">
|
||||
<button class="user-btn" id="userMenuBtn">
|
||||
<div class="user-avatar">
|
||||
<i class="fas fa-user"></i>
|
||||
</div>
|
||||
<span id="userName">Max Mustermann</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="user-dropdown" id="userDropdown">
|
||||
<a href="#settings"><i class="fas fa-cog"></i> Einstellungen</a>
|
||||
<a href="#billing"><i class="fas fa-credit-card"></i> Abrechnung</a>
|
||||
<a href="#support"><i class="fas fa-life-ring"></i> Support</a>
|
||||
<hr>
|
||||
<a href="index.html" class="logout"><i class="fas fa-sign-out-alt"></i> Abmelden</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Dashboard Layout -->
|
||||
<div class="dashboard-layout">
|
||||
<!-- Sidebar -->
|
||||
<aside class="dashboard-sidebar">
|
||||
<nav class="sidebar-nav">
|
||||
<a href="#overview" class="nav-item active" data-section="overview">
|
||||
<i class="fas fa-home"></i>
|
||||
<span>Übersicht</span>
|
||||
</a>
|
||||
<a href="#documents" class="nav-item" data-section="documents">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
<span>Dokumente</span>
|
||||
</a>
|
||||
<a href="#chatbot" class="nav-item" data-section="chatbot">
|
||||
<i class="fas fa-robot"></i>
|
||||
<span>Chatbot</span>
|
||||
</a>
|
||||
<a href="#embed" class="nav-item" data-section="embed">
|
||||
<i class="fas fa-code"></i>
|
||||
<span>Einbinden</span>
|
||||
</a>
|
||||
<a href="#analytics" class="nav-item" data-section="analytics">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
<span>Analytics</span>
|
||||
</a>
|
||||
<a href="#settings" class="nav-item" data-section="settings">
|
||||
<i class="fas fa-cog"></i>
|
||||
<span>Einstellungen</span>
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<!-- Upgrade CTA -->
|
||||
<div class="sidebar-cta">
|
||||
<div class="cta-icon">
|
||||
<i class="fas fa-crown"></i>
|
||||
</div>
|
||||
<h4>Upgrade auf Starter</h4>
|
||||
<p>Unbegrenzte Dokumente & mehr Features</p>
|
||||
<a href="#upgrade" class="btn btn-primary btn-sm btn-block">
|
||||
<span class="discount-badge">30% Rabatt</span>
|
||||
Jetzt upgraden
|
||||
</a>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main Content -->
|
||||
<main class="dashboard-main">
|
||||
<!-- Overview Section -->
|
||||
<section id="overview" class="dashboard-section active">
|
||||
<div class="section-header">
|
||||
<h1>Willkommen zurück! 👋</h1>
|
||||
<p>Hier ist eine Übersicht Ihres Chatbots</p>
|
||||
</div>
|
||||
|
||||
<!-- Stats Cards -->
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon blue">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<span class="stat-value" id="docCount">0</span>
|
||||
<span class="stat-label">Dokumente</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon green">
|
||||
<i class="fas fa-comments"></i>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<span class="stat-value" id="messageCount">0</span>
|
||||
<span class="stat-label">Nachrichten</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon purple">
|
||||
<i class="fas fa-users"></i>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<span class="stat-value" id="visitorCount">0</span>
|
||||
<span class="stat-label">Besucher</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon orange">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<span class="stat-value" id="satisfactionRate">-</span>
|
||||
<span class="stat-label">Zufriedenheit</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="quick-actions">
|
||||
<h2>Schnellstart</h2>
|
||||
<div class="actions-grid">
|
||||
<a href="#documents" class="action-card" data-section="documents">
|
||||
<div class="action-icon">
|
||||
<i class="fas fa-upload"></i>
|
||||
</div>
|
||||
<h3>PDF hochladen</h3>
|
||||
<p>Fügen Sie neue Dokumente zu Ihrer Wissensdatenbank hinzu</p>
|
||||
</a>
|
||||
<a href="#embed" class="action-card" data-section="embed">
|
||||
<div class="action-icon">
|
||||
<i class="fas fa-code"></i>
|
||||
</div>
|
||||
<h3>Code kopieren</h3>
|
||||
<p>Holen Sie sich den Embed-Code für Ihre Website</p>
|
||||
</a>
|
||||
<a href="#chatbot" class="action-card" data-section="chatbot">
|
||||
<div class="action-icon">
|
||||
<i class="fas fa-comment-dots"></i>
|
||||
</div>
|
||||
<h3>Chatbot testen</h3>
|
||||
<p>Testen Sie Ihren Chatbot live</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trial Banner -->
|
||||
<div class="trial-banner" id="trialBanner">
|
||||
<div class="banner-content">
|
||||
<div class="banner-icon">
|
||||
<i class="fas fa-gift"></i>
|
||||
</div>
|
||||
<div class="banner-text">
|
||||
<h3>🎉 Exklusives Angebot: 30% Frühbucher-Rabatt!</h3>
|
||||
<p>Upgraden Sie jetzt und sparen Sie €176,40 im ersten Jahr. Angebot endet in <strong id="offerCountdown">48:00:00</strong></p>
|
||||
</div>
|
||||
<a href="#upgrade" class="btn btn-primary">
|
||||
Jetzt für €34,30/Monat upgraden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Documents Section -->
|
||||
<section id="documents" class="dashboard-section">
|
||||
<div class="section-header">
|
||||
<h1>Dokumente</h1>
|
||||
<p>Verwalten Sie Ihre Wissensdatenbank</p>
|
||||
</div>
|
||||
|
||||
<!-- Upload Area -->
|
||||
<div class="upload-area" id="uploadArea">
|
||||
<div class="upload-content">
|
||||
<div class="upload-icon">
|
||||
<i class="fas fa-cloud-upload-alt"></i>
|
||||
</div>
|
||||
<h3>PDF-Dateien hochladen</h3>
|
||||
<p>Ziehen Sie Dateien hierher oder klicken Sie zum Auswählen</p>
|
||||
<input type="file" id="fileInput" accept=".pdf" multiple hidden>
|
||||
<button class="btn btn-primary" onclick="document.getElementById('fileInput').click()">
|
||||
<i class="fas fa-plus"></i> Dateien auswählen
|
||||
</button>
|
||||
<p class="upload-hint">Unterstützt: PDF (max. 10MB pro Datei)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Upload Progress -->
|
||||
<div class="upload-progress" id="uploadProgress" style="display: none;">
|
||||
<div class="progress-header">
|
||||
<span>Wird hochgeladen...</span>
|
||||
<span id="uploadPercent">0%</span>
|
||||
</div>
|
||||
<div class="progress-bar">
|
||||
<div class="progress-fill" id="progressFill"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Documents List -->
|
||||
<div class="documents-list">
|
||||
<div class="list-header">
|
||||
<h2>Hochgeladene Dokumente</h2>
|
||||
<span class="doc-count" id="totalDocs">0 Dokumente</span>
|
||||
</div>
|
||||
<div class="documents-table" id="documentsTable">
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<h3>Noch keine Dokumente</h3>
|
||||
<p>Laden Sie Ihr erstes PDF hoch, um zu beginnen</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Chatbot Section -->
|
||||
<section id="chatbot" class="dashboard-section">
|
||||
<div class="section-header">
|
||||
<h1>Chatbot testen</h1>
|
||||
<p>Testen Sie Ihren Chatbot mit Ihren hochgeladenen Dokumenten</p>
|
||||
</div>
|
||||
|
||||
<div class="chatbot-test-container">
|
||||
<div class="chat-window">
|
||||
<div class="chat-header">
|
||||
<div class="chat-avatar">
|
||||
<i class="fas fa-robot"></i>
|
||||
</div>
|
||||
<div class="chat-info">
|
||||
<span class="chat-name">Ihr Chatbot</span>
|
||||
<span class="chat-status"><i class="fas fa-circle"></i> Online</span>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-outline" id="clearChat">
|
||||
<i class="fas fa-trash"></i> Leeren
|
||||
</button>
|
||||
</div>
|
||||
<div class="chat-messages" id="chatMessages">
|
||||
<div class="message bot">
|
||||
<p>Hallo! Ich bin Ihr KI-Assistent. Wie kann ich Ihnen helfen?</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-input-area">
|
||||
<input type="text" id="chatInput" placeholder="Stellen Sie eine Frage...">
|
||||
<button class="send-btn" id="sendBtn">
|
||||
<i class="fas fa-paper-plane"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-tips">
|
||||
<h3>💡 Tipps</h3>
|
||||
<ul>
|
||||
<li>Stellen Sie Fragen zu Ihren hochgeladenen Dokumenten</li>
|
||||
<li>Der Bot antwortet basierend auf Ihrer Wissensdatenbank</li>
|
||||
<li>Je mehr Dokumente, desto besser die Antworten</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Embed Section -->
|
||||
<section id="embed" class="dashboard-section">
|
||||
<div class="section-header">
|
||||
<h1>Chatbot einbinden</h1>
|
||||
<p>Integrieren Sie den Chatbot in Ihre Website</p>
|
||||
</div>
|
||||
|
||||
<div class="embed-container">
|
||||
<!-- Embed Code -->
|
||||
<div class="embed-card">
|
||||
<h2><i class="fas fa-code"></i> Embed-Code</h2>
|
||||
<p>Kopieren Sie diesen Code und fügen Sie ihn vor dem <code></body></code>-Tag Ihrer Website ein:</p>
|
||||
|
||||
<div class="code-block">
|
||||
<pre id="embedCode"><script src="https://botkonzept.de/embed/<span id="customerId">IHRE-ID</span>.js"></script></pre>
|
||||
<button class="copy-btn" onclick="copyEmbedCode()">
|
||||
<i class="fas fa-copy"></i> Kopieren
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="copy-success" id="copySuccess" style="display: none;">
|
||||
<i class="fas fa-check"></i> Code kopiert!
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Webhook URLs -->
|
||||
<div class="embed-card">
|
||||
<h2><i class="fas fa-link"></i> API-Endpunkte</h2>
|
||||
<p>Für fortgeschrittene Integrationen:</p>
|
||||
|
||||
<div class="endpoint-list">
|
||||
<div class="endpoint-item">
|
||||
<label>Chat-Webhook:</label>
|
||||
<div class="endpoint-url">
|
||||
<code id="chatWebhook">https://sb-XXXXX.userman.de/webhook/rag-chat-webhook/chat</code>
|
||||
<button class="copy-btn-sm" onclick="copyToClipboard('chatWebhook')">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="endpoint-item">
|
||||
<label>Upload-Formular:</label>
|
||||
<div class="endpoint-url">
|
||||
<code id="uploadUrl">https://sb-XXXXX.userman.de/form/rag-upload-form</code>
|
||||
<button class="copy-btn-sm" onclick="copyToClipboard('uploadUrl')">
|
||||
<i class="fas fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Installation Guide -->
|
||||
<div class="embed-card">
|
||||
<h2><i class="fas fa-book"></i> Installationsanleitung</h2>
|
||||
|
||||
<div class="install-steps">
|
||||
<div class="install-step">
|
||||
<div class="step-num">1</div>
|
||||
<div class="step-content">
|
||||
<h4>Code kopieren</h4>
|
||||
<p>Klicken Sie auf "Kopieren" um den Embed-Code in die Zwischenablage zu kopieren.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="install-step">
|
||||
<div class="step-num">2</div>
|
||||
<div class="step-content">
|
||||
<h4>In Website einfügen</h4>
|
||||
<p>Fügen Sie den Code vor dem schließenden <code></body></code>-Tag ein.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="install-step">
|
||||
<div class="step-num">3</div>
|
||||
<div class="step-content">
|
||||
<h4>Fertig!</h4>
|
||||
<p>Der Chatbot erscheint automatisch unten rechts auf Ihrer Website.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="platform-guides">
|
||||
<h4>Plattform-spezifische Anleitungen:</h4>
|
||||
<div class="platform-links">
|
||||
<a href="#" class="platform-link">
|
||||
<i class="fab fa-wordpress"></i> WordPress
|
||||
</a>
|
||||
<a href="#" class="platform-link">
|
||||
<i class="fab fa-shopify"></i> Shopify
|
||||
</a>
|
||||
<a href="#" class="platform-link">
|
||||
<i class="fab fa-wix"></i> Wix
|
||||
</a>
|
||||
<a href="#" class="platform-link">
|
||||
<i class="fab fa-squarespace"></i> Squarespace
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Analytics Section -->
|
||||
<section id="analytics" class="dashboard-section">
|
||||
<div class="section-header">
|
||||
<h1>Analytics</h1>
|
||||
<p>Verstehen Sie, wie Besucher mit Ihrem Chatbot interagieren</p>
|
||||
</div>
|
||||
|
||||
<div class="analytics-placeholder">
|
||||
<div class="placeholder-icon">
|
||||
<i class="fas fa-chart-bar"></i>
|
||||
</div>
|
||||
<h3>Analytics verfügbar im Starter-Plan</h3>
|
||||
<p>Upgraden Sie, um detaillierte Statistiken zu sehen:</p>
|
||||
<ul>
|
||||
<li><i class="fas fa-check"></i> Häufigste Fragen</li>
|
||||
<li><i class="fas fa-check"></i> Antwortqualität</li>
|
||||
<li><i class="fas fa-check"></i> Besucherstatistiken</li>
|
||||
<li><i class="fas fa-check"></i> Conversion-Tracking</li>
|
||||
</ul>
|
||||
<a href="#upgrade" class="btn btn-primary">
|
||||
<i class="fas fa-crown"></i> Jetzt upgraden
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Settings Section -->
|
||||
<section id="settings" class="dashboard-section">
|
||||
<div class="section-header">
|
||||
<h1>Einstellungen</h1>
|
||||
<p>Passen Sie Ihren Chatbot an</p>
|
||||
</div>
|
||||
|
||||
<div class="settings-grid">
|
||||
<!-- Appearance Settings -->
|
||||
<div class="settings-card">
|
||||
<h2><i class="fas fa-palette"></i> Erscheinungsbild</h2>
|
||||
|
||||
<div class="setting-group">
|
||||
<label>Primärfarbe</label>
|
||||
<div class="color-picker">
|
||||
<input type="color" id="primaryColor" value="#6366f1">
|
||||
<span>#6366f1</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label>Chatbot-Name</label>
|
||||
<input type="text" id="botName" value="Assistent" placeholder="z.B. Support-Bot">
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label>Begrüßungsnachricht</label>
|
||||
<textarea id="welcomeMessage" rows="3">Hallo! Wie kann ich Ihnen helfen?</textarea>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary" onclick="saveSettings()">
|
||||
<i class="fas fa-save"></i> Speichern
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Account Settings -->
|
||||
<div class="settings-card">
|
||||
<h2><i class="fas fa-user"></i> Konto</h2>
|
||||
|
||||
<div class="setting-group">
|
||||
<label>E-Mail</label>
|
||||
<input type="email" id="accountEmail" value="max@beispiel.de" disabled>
|
||||
</div>
|
||||
|
||||
<div class="setting-group">
|
||||
<label>Plan</label>
|
||||
<div class="plan-info">
|
||||
<span class="plan-badge trial">Trial</span>
|
||||
<span>Endet am <strong id="trialEndDate">01.02.2025</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="#upgrade" class="btn btn-outline btn-block">
|
||||
<i class="fas fa-crown"></i> Plan upgraden
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="js/dashboard.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
595
index.html
Normal file
595
index.html
Normal file
@@ -0,0 +1,595 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="BotKonzept - Ihr KI-Chatbot für die Website. Einfach einrichten, PDF hochladen, fertig!">
|
||||
<meta name="keywords" content="KI Chatbot, Website Chatbot, RAG, PDF Chatbot, Kundenservice Automation">
|
||||
<title>BotKonzept - KI-Chatbot für Ihre Website</title>
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/svg+xml" href="logo/20250119_Logo_Botkozept.svg">
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
|
||||
|
||||
<!-- Custom CSS -->
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<!-- Navigation -->
|
||||
<nav class="navbar" id="navbar">
|
||||
<div class="container">
|
||||
<a href="#" class="logo">
|
||||
<img src="logo/20250119_Logo_Botkozept.svg" alt="BotKonzept Logo">
|
||||
<span>BotKonzept</span>
|
||||
</a>
|
||||
<div class="nav-links" id="navLinks">
|
||||
<a href="#features">Features</a>
|
||||
<a href="#how-it-works">So funktioniert's</a>
|
||||
<a href="#pricing">Preise</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
<a href="#register" class="btn btn-primary btn-sm">Kostenlos testen</a>
|
||||
</div>
|
||||
<button class="mobile-menu-btn" id="mobileMenuBtn" aria-label="Menü öffnen">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Hero Section -->
|
||||
<section class="hero">
|
||||
<div class="container">
|
||||
<div class="hero-content">
|
||||
<div class="hero-badge">
|
||||
<i class="fas fa-rocket"></i>
|
||||
<span>7 Tage kostenlos testen</span>
|
||||
</div>
|
||||
<h1>Ihr intelligenter <span class="gradient-text">KI-Chatbot</span> für die Website</h1>
|
||||
<p class="hero-subtitle">
|
||||
Laden Sie einfach Ihre PDFs hoch und Ihr Chatbot beantwortet Kundenfragen automatisch.
|
||||
Keine Programmierung erforderlich – in 5 Minuten einsatzbereit.
|
||||
</p>
|
||||
<div class="hero-cta">
|
||||
<a href="#register" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-play"></i>
|
||||
Jetzt kostenlos starten
|
||||
</a>
|
||||
<a href="#how-it-works" class="btn btn-outline btn-lg">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
Mehr erfahren
|
||||
</a>
|
||||
</div>
|
||||
<div class="hero-stats">
|
||||
<div class="stat">
|
||||
<span class="stat-number">5 Min</span>
|
||||
<span class="stat-label">Setup-Zeit</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number">100%</span>
|
||||
<span class="stat-label">DSGVO-konform</span>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<span class="stat-number">24/7</span>
|
||||
<span class="stat-label">Verfügbar</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-visual">
|
||||
<div class="chat-preview">
|
||||
<div class="chat-header">
|
||||
<div class="chat-avatar">
|
||||
<i class="fas fa-robot"></i>
|
||||
</div>
|
||||
<div class="chat-info">
|
||||
<span class="chat-name">BotKonzept Assistent</span>
|
||||
<span class="chat-status"><i class="fas fa-circle"></i> Online</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-messages">
|
||||
<div class="message bot">
|
||||
<p>Hallo! 👋 Wie kann ich Ihnen heute helfen?</p>
|
||||
</div>
|
||||
<div class="message user">
|
||||
<p>Was sind Ihre Öffnungszeiten?</p>
|
||||
</div>
|
||||
<div class="message bot">
|
||||
<p>Unsere Öffnungszeiten sind Montag bis Freitag von 9:00 bis 18:00 Uhr. Am Wochenende sind wir geschlossen.</p>
|
||||
</div>
|
||||
<div class="message user">
|
||||
<p>Wie kann ich eine Bestellung aufgeben?</p>
|
||||
</div>
|
||||
<div class="message bot typing">
|
||||
<span class="typing-indicator">
|
||||
<span></span><span></span><span></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chat-input">
|
||||
<input type="text" placeholder="Nachricht eingeben...">
|
||||
<button><i class="fas fa-paper-plane"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-bg">
|
||||
<div class="gradient-orb orb-1"></div>
|
||||
<div class="gradient-orb orb-2"></div>
|
||||
<div class="gradient-orb orb-3"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Trusted By Section -->
|
||||
<section class="trusted-by">
|
||||
<div class="container">
|
||||
<p class="trusted-label">Vertraut von innovativen Unternehmen</p>
|
||||
<div class="trusted-logos">
|
||||
<div class="logo-placeholder"><i class="fas fa-building"></i> Unternehmen A</div>
|
||||
<div class="logo-placeholder"><i class="fas fa-building"></i> Unternehmen B</div>
|
||||
<div class="logo-placeholder"><i class="fas fa-building"></i> Unternehmen C</div>
|
||||
<div class="logo-placeholder"><i class="fas fa-building"></i> Unternehmen D</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Features Section -->
|
||||
<section class="features" id="features">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">Features</span>
|
||||
<h2>Alles was Sie für einen erfolgreichen Chatbot brauchen</h2>
|
||||
<p>Leistungsstarke Funktionen, die Ihren Kundenservice revolutionieren</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</div>
|
||||
<h3>PDF-Upload</h3>
|
||||
<p>Laden Sie einfach Ihre Dokumente hoch. Der Chatbot lernt automatisch aus Ihren Inhalten.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-brain"></i>
|
||||
</div>
|
||||
<h3>KI-gestützte Antworten</h3>
|
||||
<p>Modernste KI-Technologie für natürliche und präzise Antworten auf Kundenfragen.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-code"></i>
|
||||
</div>
|
||||
<h3>Einfache Integration</h3>
|
||||
<p>Ein Zeile Code – mehr brauchen Sie nicht. Funktioniert mit jeder Website.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-shield-alt"></i>
|
||||
</div>
|
||||
<h3>DSGVO-konform</h3>
|
||||
<p>Alle Daten werden in Deutschland gehostet. 100% DSGVO-konform.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-palette"></i>
|
||||
</div>
|
||||
<h3>Anpassbares Design</h3>
|
||||
<p>Passen Sie Farben und Stil an Ihre Marke an. Ihr Chatbot, Ihr Look.</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
<i class="fas fa-chart-line"></i>
|
||||
</div>
|
||||
<h3>Analytics Dashboard</h3>
|
||||
<p>Verstehen Sie, was Ihre Kunden fragen. Detaillierte Statistiken und Insights.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- How It Works Section -->
|
||||
<section class="how-it-works" id="how-it-works">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">So funktioniert's</span>
|
||||
<h2>In 3 einfachen Schritten zum eigenen KI-Chatbot</h2>
|
||||
<p>Keine technischen Kenntnisse erforderlich</p>
|
||||
</div>
|
||||
<div class="steps">
|
||||
<div class="step">
|
||||
<div class="step-number">1</div>
|
||||
<div class="step-content">
|
||||
<h3>Registrieren</h3>
|
||||
<p>Erstellen Sie Ihr kostenloses Konto in weniger als einer Minute. Keine Kreditkarte erforderlich.</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<i class="fas fa-user-plus"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-connector"></div>
|
||||
<div class="step">
|
||||
<div class="step-number">2</div>
|
||||
<div class="step-content">
|
||||
<h3>PDFs hochladen</h3>
|
||||
<p>Laden Sie Ihre Dokumente hoch – FAQs, Produktinfos, Anleitungen. Der Bot lernt automatisch.</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<i class="fas fa-cloud-upload-alt"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-connector"></div>
|
||||
<div class="step">
|
||||
<div class="step-number">3</div>
|
||||
<div class="step-content">
|
||||
<h3>Code einbinden</h3>
|
||||
<p>Kopieren Sie den Code-Snippet und fügen Sie ihn in Ihre Website ein. Fertig!</p>
|
||||
</div>
|
||||
<div class="step-icon">
|
||||
<i class="fas fa-code"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-preview">
|
||||
<div class="code-header">
|
||||
<span class="code-dot red"></span>
|
||||
<span class="code-dot yellow"></span>
|
||||
<span class="code-dot green"></span>
|
||||
<span class="code-title">Ihr Embed-Code</span>
|
||||
</div>
|
||||
<pre><code><script src="https://botkonzept.de/embed/IHRE-ID.js"></script></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Pricing Section -->
|
||||
<section class="pricing" id="pricing">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">Preise</span>
|
||||
<h2>Transparente Preise, keine versteckten Kosten</h2>
|
||||
<p>Starten Sie kostenlos und upgraden Sie, wenn Sie bereit sind</p>
|
||||
</div>
|
||||
<div class="pricing-grid">
|
||||
<!-- Trial Plan -->
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-header">
|
||||
<h3>Trial</h3>
|
||||
<div class="price">
|
||||
<span class="currency">€</span>
|
||||
<span class="amount">0</span>
|
||||
<span class="period">/7 Tage</span>
|
||||
</div>
|
||||
<p class="pricing-description">Perfekt zum Testen</p>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li><i class="fas fa-check"></i> 100 Dokumente</li>
|
||||
<li><i class="fas fa-check"></i> 1.000 Nachrichten</li>
|
||||
<li><i class="fas fa-check"></i> 1 Chatbot</li>
|
||||
<li><i class="fas fa-check"></i> Standard Support</li>
|
||||
<li class="disabled"><i class="fas fa-times"></i> Custom Branding</li>
|
||||
<li class="disabled"><i class="fas fa-times"></i> Analytics</li>
|
||||
</ul>
|
||||
<a href="#register" class="btn btn-outline btn-block">Kostenlos starten</a>
|
||||
</div>
|
||||
|
||||
<!-- Starter Plan -->
|
||||
<div class="pricing-card featured">
|
||||
<div class="pricing-badge">Beliebt</div>
|
||||
<div class="pricing-header">
|
||||
<h3>Starter</h3>
|
||||
<div class="price">
|
||||
<span class="currency">€</span>
|
||||
<span class="amount">49</span>
|
||||
<span class="period">/Monat</span>
|
||||
</div>
|
||||
<p class="pricing-description">Für kleine Unternehmen</p>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li><i class="fas fa-check"></i> Unbegrenzte Dokumente</li>
|
||||
<li><i class="fas fa-check"></i> 10.000 Nachrichten/Monat</li>
|
||||
<li><i class="fas fa-check"></i> 1 Chatbot</li>
|
||||
<li><i class="fas fa-check"></i> Prioritäts-Support</li>
|
||||
<li><i class="fas fa-check"></i> Custom Branding</li>
|
||||
<li><i class="fas fa-check"></i> Analytics Dashboard</li>
|
||||
</ul>
|
||||
<a href="#register" class="btn btn-primary btn-block">Jetzt starten</a>
|
||||
<p class="pricing-note">
|
||||
<i class="fas fa-gift"></i>
|
||||
<span class="discount-tag">30% Rabatt</span> bei Upgrade innerhalb von 3 Tagen
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Business Plan -->
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-header">
|
||||
<h3>Business</h3>
|
||||
<div class="price">
|
||||
<span class="currency">€</span>
|
||||
<span class="amount">149</span>
|
||||
<span class="period">/Monat</span>
|
||||
</div>
|
||||
<p class="pricing-description">Für wachsende Teams</p>
|
||||
</div>
|
||||
<ul class="pricing-features">
|
||||
<li><i class="fas fa-check"></i> Unbegrenzte Dokumente</li>
|
||||
<li><i class="fas fa-check"></i> 50.000 Nachrichten/Monat</li>
|
||||
<li><i class="fas fa-check"></i> 5 Chatbots</li>
|
||||
<li><i class="fas fa-check"></i> Dedizierter Support</li>
|
||||
<li><i class="fas fa-check"></i> API-Zugriff</li>
|
||||
<li><i class="fas fa-check"></i> SLA-Garantie</li>
|
||||
</ul>
|
||||
<a href="#register" class="btn btn-outline btn-block">Kontakt aufnehmen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Discount Timeline -->
|
||||
<div class="discount-timeline">
|
||||
<h3><i class="fas fa-clock"></i> Frühbucher-Rabatte</h3>
|
||||
<div class="timeline">
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-marker active"></div>
|
||||
<div class="timeline-content">
|
||||
<span class="timeline-day">Tag 1-3</span>
|
||||
<span class="timeline-discount">30% Rabatt</span>
|
||||
<span class="timeline-price">€34,30/Monat</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-marker"></div>
|
||||
<div class="timeline-content">
|
||||
<span class="timeline-day">Tag 4-5</span>
|
||||
<span class="timeline-discount">15% Rabatt</span>
|
||||
<span class="timeline-price">€41,65/Monat</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="timeline-item">
|
||||
<div class="timeline-marker"></div>
|
||||
<div class="timeline-content">
|
||||
<span class="timeline-day">Tag 6-7</span>
|
||||
<span class="timeline-discount">Normalpreis</span>
|
||||
<span class="timeline-price">€49/Monat</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Registration Section -->
|
||||
<section class="register" id="register">
|
||||
<div class="container">
|
||||
<div class="register-wrapper">
|
||||
<div class="register-info">
|
||||
<h2>Starten Sie Ihre <span class="gradient-text">7-Tage Trial</span></h2>
|
||||
<p>Keine Kreditkarte erforderlich. Voller Funktionsumfang. Jederzeit kündbar.</p>
|
||||
<ul class="register-benefits">
|
||||
<li><i class="fas fa-check-circle"></i> Sofortiger Zugang</li>
|
||||
<li><i class="fas fa-check-circle"></i> Keine Zahlungsdaten nötig</li>
|
||||
<li><i class="fas fa-check-circle"></i> Persönlicher Support</li>
|
||||
<li><i class="fas fa-check-circle"></i> Alle Features inklusive</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="register-form-wrapper">
|
||||
<form id="registerForm" class="register-form">
|
||||
<div class="form-row">
|
||||
<div class="form-group">
|
||||
<label for="firstName">Vorname *</label>
|
||||
<input type="text" id="firstName" name="firstName" required placeholder="Max">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastName">Nachname *</label>
|
||||
<input type="text" id="lastName" name="lastName" required placeholder="Mustermann">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="email">E-Mail-Adresse *</label>
|
||||
<input type="email" id="email" name="email" required placeholder="max@beispiel.de">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="company">Unternehmen (optional)</label>
|
||||
<input type="text" id="company" name="company" placeholder="Muster GmbH">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="website">Website (optional)</label>
|
||||
<input type="url" id="website" name="website" placeholder="https://www.beispiel.de">
|
||||
</div>
|
||||
<div class="form-group checkbox-group">
|
||||
<input type="checkbox" id="privacy" name="privacy" required>
|
||||
<label for="privacy">
|
||||
Ich akzeptiere die <a href="#" target="_blank">Datenschutzerklärung</a> und
|
||||
<a href="#" target="_blank">AGB</a> *
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group checkbox-group">
|
||||
<input type="checkbox" id="newsletter" name="newsletter">
|
||||
<label for="newsletter">
|
||||
Ich möchte Updates und Tipps per E-Mail erhalten (optional)
|
||||
</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block" id="submitBtn">
|
||||
<span class="btn-text">Kostenlos registrieren</span>
|
||||
<span class="btn-loading" style="display: none;">
|
||||
<i class="fas fa-spinner fa-spin"></i> Wird erstellt...
|
||||
</span>
|
||||
</button>
|
||||
</form>
|
||||
<div id="formSuccess" class="form-success" style="display: none;">
|
||||
<div class="success-icon">
|
||||
<i class="fas fa-check-circle"></i>
|
||||
</div>
|
||||
<h3>Willkommen bei BotKonzept!</h3>
|
||||
<p>Ihre Instanz wird gerade erstellt. Sie erhalten in Kürze eine E-Mail mit Ihren Zugangsdaten.</p>
|
||||
<div class="success-details">
|
||||
<p><strong>Nächste Schritte:</strong></p>
|
||||
<ol>
|
||||
<li>Prüfen Sie Ihren Posteingang</li>
|
||||
<li>Klicken Sie auf den Aktivierungslink</li>
|
||||
<li>Laden Sie Ihr erstes PDF hoch</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div id="formError" class="form-error" style="display: none;">
|
||||
<div class="error-icon">
|
||||
<i class="fas fa-exclamation-circle"></i>
|
||||
</div>
|
||||
<h3>Ups, etwas ist schiefgelaufen</h3>
|
||||
<p id="errorMessage">Bitte versuchen Sie es später erneut.</p>
|
||||
<button class="btn btn-outline" onclick="resetForm()">Erneut versuchen</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- FAQ Section -->
|
||||
<section class="faq" id="faq">
|
||||
<div class="container">
|
||||
<div class="section-header">
|
||||
<span class="section-badge">FAQ</span>
|
||||
<h2>Häufig gestellte Fragen</h2>
|
||||
<p>Alles was Sie wissen müssen</p>
|
||||
</div>
|
||||
<div class="faq-grid">
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Wie funktioniert der KI-Chatbot?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Unser Chatbot nutzt modernste KI-Technologie (RAG - Retrieval Augmented Generation).
|
||||
Sie laden Ihre Dokumente hoch, und der Bot durchsucht diese, um präzise Antworten auf
|
||||
Kundenfragen zu geben. Die KI versteht den Kontext und formuliert natürliche Antworten.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Welche Dateiformate werden unterstützt?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Aktuell unterstützen wir PDF-Dateien. Weitere Formate wie Word, Excel und
|
||||
Textdateien sind in Planung. Sie können beliebig viele PDFs hochladen –
|
||||
FAQs, Produktkataloge, Anleitungen, etc.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Ist der Service DSGVO-konform?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Ja, 100%! Alle Daten werden ausschließlich auf Servern in Deutschland gehostet.
|
||||
Wir verarbeiten keine Daten außerhalb der EU. Sie erhalten einen
|
||||
Auftragsverarbeitungsvertrag (AVV) auf Anfrage.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Kann ich den Chatbot an mein Design anpassen?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Ja! Im Starter- und Business-Plan können Sie Farben, Logo und Begrüßungstext
|
||||
anpassen. Der Chatbot fügt sich nahtlos in Ihr Website-Design ein.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Was passiert nach der Trial-Phase?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Nach 7 Tagen endet Ihre Trial automatisch. Sie können jederzeit auf einen
|
||||
bezahlten Plan upgraden. Wenn Sie innerhalb der ersten 3 Tage upgraden,
|
||||
erhalten Sie 30% Rabatt!</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="faq-item">
|
||||
<button class="faq-question">
|
||||
<span>Wie integriere ich den Chatbot in meine Website?</span>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</button>
|
||||
<div class="faq-answer">
|
||||
<p>Ganz einfach! Sie erhalten einen Code-Snippet, den Sie vor dem </body>-Tag
|
||||
Ihrer Website einfügen. Das funktioniert mit WordPress, Shopify, Wix,
|
||||
und jeder anderen Website.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- CTA Section -->
|
||||
<section class="cta">
|
||||
<div class="container">
|
||||
<div class="cta-content">
|
||||
<h2>Bereit, Ihren Kundenservice zu revolutionieren?</h2>
|
||||
<p>Starten Sie noch heute Ihre kostenlose 7-Tage-Trial</p>
|
||||
<a href="#register" class="btn btn-white btn-lg">
|
||||
<i class="fas fa-rocket"></i>
|
||||
Jetzt kostenlos starten
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Footer -->
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-grid">
|
||||
<div class="footer-brand">
|
||||
<a href="#" class="logo">
|
||||
<img src="logo/20250119_Logo_Botkozept.svg" alt="BotKonzept Logo">
|
||||
<span>BotKonzept</span>
|
||||
</a>
|
||||
<p>Ihr intelligenter KI-Chatbot für besseren Kundenservice.</p>
|
||||
<div class="social-links">
|
||||
<a href="#" aria-label="LinkedIn"><i class="fab fa-linkedin"></i></a>
|
||||
<a href="#" aria-label="Twitter"><i class="fab fa-twitter"></i></a>
|
||||
<a href="#" aria-label="GitHub"><i class="fab fa-github"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Produkt</h4>
|
||||
<ul>
|
||||
<li><a href="#features">Features</a></li>
|
||||
<li><a href="#pricing">Preise</a></li>
|
||||
<li><a href="#faq">FAQ</a></li>
|
||||
<li><a href="#">Dokumentation</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Unternehmen</h4>
|
||||
<ul>
|
||||
<li><a href="#">Über uns</a></li>
|
||||
<li><a href="#">Blog</a></li>
|
||||
<li><a href="#">Karriere</a></li>
|
||||
<li><a href="#">Kontakt</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer-links">
|
||||
<h4>Rechtliches</h4>
|
||||
<ul>
|
||||
<li><a href="#">Impressum</a></li>
|
||||
<li><a href="#">Datenschutz</a></li>
|
||||
<li><a href="#">AGB</a></li>
|
||||
<li><a href="#">Cookie-Einstellungen</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">
|
||||
<p>© 2025 BotKonzept. Alle Rechte vorbehalten.</p>
|
||||
<p>Made with <i class="fas fa-heart"></i> in Germany</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<!-- Custom JS -->
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
744
js/dashboard.js
Normal file
744
js/dashboard.js
Normal file
@@ -0,0 +1,744 @@
|
||||
/**
|
||||
* BotKonzept Dashboard JavaScript
|
||||
* ================================
|
||||
* Handles all dashboard functionality
|
||||
*/
|
||||
|
||||
// Configuration
|
||||
const DASHBOARD_CONFIG = {
|
||||
// API Endpoints - Update for production
|
||||
API_BASE_URL: 'https://api.botkonzept.de',
|
||||
CHAT_WEBHOOK_URL: '', // Will be set from customer data
|
||||
UPLOAD_URL: '', // Will be set from customer data
|
||||
|
||||
// Customer data (loaded from localStorage or API)
|
||||
customerId: null,
|
||||
customerData: null,
|
||||
|
||||
// Trial settings
|
||||
trialDays: 7,
|
||||
discountDay3: 0.30, // 30% discount
|
||||
discountDay5: 0.15, // 15% discount
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// DOM Ready
|
||||
// ============================================
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initDashboard();
|
||||
initNavigation();
|
||||
initUserMenu();
|
||||
initFileUpload();
|
||||
initChatbot();
|
||||
initSectionNavigation();
|
||||
loadCustomerData();
|
||||
updateTrialStatus();
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Dashboard Initialization
|
||||
// ============================================
|
||||
function initDashboard() {
|
||||
// Check if user is logged in (for demo, we'll simulate this)
|
||||
const isLoggedIn = localStorage.getItem('botkonzept_session') || true; // Demo mode
|
||||
|
||||
if (!isLoggedIn) {
|
||||
window.location.href = 'index.html';
|
||||
return;
|
||||
}
|
||||
|
||||
// Load customer data from localStorage or use demo data
|
||||
const storedData = localStorage.getItem('botkonzept_customer');
|
||||
if (storedData) {
|
||||
DASHBOARD_CONFIG.customerData = JSON.parse(storedData);
|
||||
} else {
|
||||
// Demo data
|
||||
DASHBOARD_CONFIG.customerData = {
|
||||
id: 'demo-' + Date.now(),
|
||||
firstName: 'Max',
|
||||
lastName: 'Mustermann',
|
||||
email: 'max@beispiel.de',
|
||||
company: 'Muster GmbH',
|
||||
trialStartDate: new Date().toISOString(),
|
||||
instanceUrl: 'https://sb-demo.userman.de',
|
||||
chatWebhook: 'https://sb-demo.userman.de/webhook/rag-chat-webhook/chat',
|
||||
uploadUrl: 'https://sb-demo.userman.de/form/rag-upload-form',
|
||||
};
|
||||
}
|
||||
|
||||
// Update UI with customer data
|
||||
updateCustomerUI();
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Navigation
|
||||
// ============================================
|
||||
function initNavigation() {
|
||||
// Sidebar navigation
|
||||
const navItems = document.querySelectorAll('.sidebar-nav .nav-item');
|
||||
const sections = document.querySelectorAll('.dashboard-section');
|
||||
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const sectionId = item.getAttribute('data-section');
|
||||
|
||||
// Update active states
|
||||
navItems.forEach(nav => nav.classList.remove('active'));
|
||||
item.classList.add('active');
|
||||
|
||||
// Show corresponding section
|
||||
sections.forEach(section => {
|
||||
section.classList.remove('active');
|
||||
if (section.id === sectionId) {
|
||||
section.classList.add('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Update URL hash
|
||||
window.location.hash = sectionId;
|
||||
});
|
||||
});
|
||||
|
||||
// Handle initial hash
|
||||
const hash = window.location.hash.slice(1);
|
||||
if (hash) {
|
||||
const targetNav = document.querySelector(`[data-section="${hash}"]`);
|
||||
if (targetNav) {
|
||||
targetNav.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function initSectionNavigation() {
|
||||
// Quick action cards
|
||||
const actionCards = document.querySelectorAll('.action-card');
|
||||
actionCards.forEach(card => {
|
||||
card.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
const sectionId = card.getAttribute('data-section');
|
||||
const targetNav = document.querySelector(`[data-section="${sectionId}"]`);
|
||||
if (targetNav) {
|
||||
targetNav.click();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// User Menu
|
||||
// ============================================
|
||||
function initUserMenu() {
|
||||
const userBtn = document.getElementById('userMenuBtn');
|
||||
const userDropdown = document.getElementById('userDropdown');
|
||||
|
||||
if (!userBtn || !userDropdown) return;
|
||||
|
||||
userBtn.addEventListener('click', () => {
|
||||
userDropdown.classList.toggle('active');
|
||||
});
|
||||
|
||||
// Close on outside click
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!userBtn.contains(e.target) && !userDropdown.contains(e.target)) {
|
||||
userDropdown.classList.remove('active');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Customer Data
|
||||
// ============================================
|
||||
function loadCustomerData() {
|
||||
const data = DASHBOARD_CONFIG.customerData;
|
||||
if (!data) return;
|
||||
|
||||
// Update customer ID in embed code
|
||||
const customerIdEl = document.getElementById('customerId');
|
||||
if (customerIdEl) {
|
||||
customerIdEl.textContent = data.id;
|
||||
}
|
||||
|
||||
// Update webhook URLs
|
||||
const chatWebhookEl = document.getElementById('chatWebhook');
|
||||
if (chatWebhookEl && data.chatWebhook) {
|
||||
chatWebhookEl.textContent = data.chatWebhook;
|
||||
}
|
||||
|
||||
const uploadUrlEl = document.getElementById('uploadUrl');
|
||||
if (uploadUrlEl && data.uploadUrl) {
|
||||
uploadUrlEl.textContent = data.uploadUrl;
|
||||
}
|
||||
|
||||
// Update user name
|
||||
const userNameEl = document.getElementById('userName');
|
||||
if (userNameEl) {
|
||||
userNameEl.textContent = `${data.firstName} ${data.lastName}`;
|
||||
}
|
||||
|
||||
// Update account email
|
||||
const accountEmailEl = document.getElementById('accountEmail');
|
||||
if (accountEmailEl) {
|
||||
accountEmailEl.value = data.email;
|
||||
}
|
||||
}
|
||||
|
||||
function updateCustomerUI() {
|
||||
loadCustomerData();
|
||||
|
||||
// Update stats (demo data)
|
||||
updateStats({
|
||||
documents: 0,
|
||||
messages: 0,
|
||||
visitors: 0,
|
||||
satisfaction: '-'
|
||||
});
|
||||
}
|
||||
|
||||
function updateStats(stats) {
|
||||
const docCountEl = document.getElementById('docCount');
|
||||
const messageCountEl = document.getElementById('messageCount');
|
||||
const visitorCountEl = document.getElementById('visitorCount');
|
||||
const satisfactionEl = document.getElementById('satisfactionRate');
|
||||
|
||||
if (docCountEl) docCountEl.textContent = stats.documents;
|
||||
if (messageCountEl) messageCountEl.textContent = stats.messages;
|
||||
if (visitorCountEl) visitorCountEl.textContent = stats.visitors;
|
||||
if (satisfactionEl) satisfactionEl.textContent = stats.satisfaction;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Trial Status
|
||||
// ============================================
|
||||
function updateTrialStatus() {
|
||||
const data = DASHBOARD_CONFIG.customerData;
|
||||
if (!data || !data.trialStartDate) return;
|
||||
|
||||
const trialStart = new Date(data.trialStartDate);
|
||||
const now = new Date();
|
||||
const daysPassed = Math.floor((now - trialStart) / (1000 * 60 * 60 * 24));
|
||||
const daysRemaining = Math.max(0, DASHBOARD_CONFIG.trialDays - daysPassed);
|
||||
|
||||
// Update trial badge
|
||||
const trialDaysEl = document.getElementById('trialDays');
|
||||
if (trialDaysEl) {
|
||||
trialDaysEl.textContent = daysRemaining;
|
||||
}
|
||||
|
||||
// Update trial end date
|
||||
const trialEndDateEl = document.getElementById('trialEndDate');
|
||||
if (trialEndDateEl) {
|
||||
const endDate = new Date(trialStart);
|
||||
endDate.setDate(endDate.getDate() + DASHBOARD_CONFIG.trialDays);
|
||||
trialEndDateEl.textContent = formatDate(endDate);
|
||||
}
|
||||
|
||||
// Show/hide discount banner based on days
|
||||
const trialBanner = document.getElementById('trialBanner');
|
||||
if (trialBanner) {
|
||||
if (daysPassed <= 3) {
|
||||
// Show 30% discount
|
||||
trialBanner.querySelector('h3').textContent = '🎉 Exklusives Angebot: 30% Frühbucher-Rabatt!';
|
||||
trialBanner.querySelector('.btn').textContent = 'Jetzt für €34,30/Monat upgraden';
|
||||
} else if (daysPassed <= 5) {
|
||||
// Show 15% discount
|
||||
trialBanner.querySelector('h3').textContent = '⏰ Nur noch 2 Tage: 15% Rabatt!';
|
||||
trialBanner.querySelector('.btn').textContent = 'Jetzt für €41,65/Monat upgraden';
|
||||
} else {
|
||||
// Show normal price
|
||||
trialBanner.querySelector('h3').textContent = '⚠️ Ihre Trial endet bald!';
|
||||
trialBanner.querySelector('.btn').textContent = 'Jetzt für €49/Monat upgraden';
|
||||
}
|
||||
}
|
||||
|
||||
// Start countdown timer
|
||||
startOfferCountdown();
|
||||
}
|
||||
|
||||
function startOfferCountdown() {
|
||||
const countdownEl = document.getElementById('offerCountdown');
|
||||
if (!countdownEl) return;
|
||||
|
||||
// Set countdown to 48 hours from now (for demo)
|
||||
let timeRemaining = 48 * 60 * 60; // 48 hours in seconds
|
||||
|
||||
const updateCountdown = () => {
|
||||
const hours = Math.floor(timeRemaining / 3600);
|
||||
const minutes = Math.floor((timeRemaining % 3600) / 60);
|
||||
const seconds = timeRemaining % 60;
|
||||
|
||||
countdownEl.textContent = `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
|
||||
|
||||
if (timeRemaining > 0) {
|
||||
timeRemaining--;
|
||||
setTimeout(updateCountdown, 1000);
|
||||
}
|
||||
};
|
||||
|
||||
updateCountdown();
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// File Upload
|
||||
// ============================================
|
||||
function initFileUpload() {
|
||||
const uploadArea = document.getElementById('uploadArea');
|
||||
const fileInput = document.getElementById('fileInput');
|
||||
|
||||
if (!uploadArea || !fileInput) return;
|
||||
|
||||
// Drag and drop
|
||||
uploadArea.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
uploadArea.classList.add('dragover');
|
||||
});
|
||||
|
||||
uploadArea.addEventListener('dragleave', () => {
|
||||
uploadArea.classList.remove('dragover');
|
||||
});
|
||||
|
||||
uploadArea.addEventListener('drop', (e) => {
|
||||
e.preventDefault();
|
||||
uploadArea.classList.remove('dragover');
|
||||
|
||||
const files = e.dataTransfer.files;
|
||||
handleFiles(files);
|
||||
});
|
||||
|
||||
// File input change
|
||||
fileInput.addEventListener('change', () => {
|
||||
handleFiles(fileInput.files);
|
||||
});
|
||||
}
|
||||
|
||||
function handleFiles(files) {
|
||||
const validFiles = Array.from(files).filter(file => {
|
||||
if (file.type !== 'application/pdf') {
|
||||
showNotification('Nur PDF-Dateien werden unterstützt', 'error');
|
||||
return false;
|
||||
}
|
||||
if (file.size > 10 * 1024 * 1024) { // 10MB
|
||||
showNotification(`${file.name} ist zu groß (max. 10MB)`, 'error');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (validFiles.length === 0) return;
|
||||
|
||||
validFiles.forEach(file => uploadFile(file));
|
||||
}
|
||||
|
||||
async function uploadFile(file) {
|
||||
const uploadProgress = document.getElementById('uploadProgress');
|
||||
const progressFill = document.getElementById('progressFill');
|
||||
const uploadPercent = document.getElementById('uploadPercent');
|
||||
|
||||
// Show progress
|
||||
if (uploadProgress) uploadProgress.style.display = 'block';
|
||||
|
||||
try {
|
||||
// Simulate upload progress (replace with actual upload)
|
||||
for (let i = 0; i <= 100; i += 10) {
|
||||
await new Promise(resolve => setTimeout(resolve, 200));
|
||||
if (progressFill) progressFill.style.width = `${i}%`;
|
||||
if (uploadPercent) uploadPercent.textContent = `${i}%`;
|
||||
}
|
||||
|
||||
// Add document to list
|
||||
addDocumentToList({
|
||||
name: file.name,
|
||||
size: formatFileSize(file.size),
|
||||
date: new Date().toLocaleDateString('de-DE'),
|
||||
status: 'processing'
|
||||
});
|
||||
|
||||
showNotification(`${file.name} wurde hochgeladen`, 'success');
|
||||
|
||||
// Simulate processing
|
||||
setTimeout(() => {
|
||||
updateDocumentStatus(file.name, 'indexed');
|
||||
updateDocCount();
|
||||
}, 3000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Upload error:', error);
|
||||
showNotification('Fehler beim Hochladen', 'error');
|
||||
} finally {
|
||||
// Hide progress
|
||||
setTimeout(() => {
|
||||
if (uploadProgress) uploadProgress.style.display = 'none';
|
||||
if (progressFill) progressFill.style.width = '0%';
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
function addDocumentToList(doc) {
|
||||
const documentsTable = document.getElementById('documentsTable');
|
||||
if (!documentsTable) return;
|
||||
|
||||
// Remove empty state if present
|
||||
const emptyState = documentsTable.querySelector('.empty-state');
|
||||
if (emptyState) emptyState.remove();
|
||||
|
||||
const docRow = document.createElement('div');
|
||||
docRow.className = 'document-row';
|
||||
docRow.dataset.name = doc.name;
|
||||
docRow.innerHTML = `
|
||||
<div class="doc-icon">
|
||||
<i class="fas fa-file-pdf"></i>
|
||||
</div>
|
||||
<div class="doc-info">
|
||||
<div class="doc-name">${doc.name}</div>
|
||||
<div class="doc-meta">${doc.size} • ${doc.date}</div>
|
||||
</div>
|
||||
<span class="doc-status ${doc.status}">${doc.status === 'indexed' ? 'Indexiert' : 'Verarbeitung...'}</span>
|
||||
<div class="doc-actions">
|
||||
<button title="Herunterladen"><i class="fas fa-download"></i></button>
|
||||
<button class="delete" title="Löschen" onclick="deleteDocument('${doc.name}')"><i class="fas fa-trash"></i></button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
documentsTable.appendChild(docRow);
|
||||
}
|
||||
|
||||
function updateDocumentStatus(name, status) {
|
||||
const docRow = document.querySelector(`.document-row[data-name="${name}"]`);
|
||||
if (!docRow) return;
|
||||
|
||||
const statusEl = docRow.querySelector('.doc-status');
|
||||
if (statusEl) {
|
||||
statusEl.className = `doc-status ${status}`;
|
||||
statusEl.textContent = status === 'indexed' ? 'Indexiert' : 'Verarbeitung...';
|
||||
}
|
||||
}
|
||||
|
||||
function deleteDocument(name) {
|
||||
if (!confirm(`Möchten Sie "${name}" wirklich löschen?`)) return;
|
||||
|
||||
const docRow = document.querySelector(`.document-row[data-name="${name}"]`);
|
||||
if (docRow) {
|
||||
docRow.remove();
|
||||
updateDocCount();
|
||||
showNotification('Dokument gelöscht', 'success');
|
||||
}
|
||||
|
||||
// Show empty state if no documents
|
||||
const documentsTable = document.getElementById('documentsTable');
|
||||
if (documentsTable && documentsTable.children.length === 0) {
|
||||
documentsTable.innerHTML = `
|
||||
<div class="empty-state">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<h3>Noch keine Dokumente</h3>
|
||||
<p>Laden Sie Ihr erstes PDF hoch, um zu beginnen</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function updateDocCount() {
|
||||
const documentsTable = document.getElementById('documentsTable');
|
||||
const totalDocsEl = document.getElementById('totalDocs');
|
||||
const docCountEl = document.getElementById('docCount');
|
||||
|
||||
if (!documentsTable) return;
|
||||
|
||||
const count = documentsTable.querySelectorAll('.document-row').length;
|
||||
|
||||
if (totalDocsEl) totalDocsEl.textContent = `${count} Dokument${count !== 1 ? 'e' : ''}`;
|
||||
if (docCountEl) docCountEl.textContent = count;
|
||||
}
|
||||
|
||||
// Make deleteDocument available globally
|
||||
window.deleteDocument = deleteDocument;
|
||||
|
||||
// ============================================
|
||||
// Chatbot
|
||||
// ============================================
|
||||
function initChatbot() {
|
||||
const chatInput = document.getElementById('chatInput');
|
||||
const sendBtn = document.getElementById('sendBtn');
|
||||
const clearBtn = document.getElementById('clearChat');
|
||||
|
||||
if (!chatInput || !sendBtn) return;
|
||||
|
||||
// Send message on button click
|
||||
sendBtn.addEventListener('click', () => sendMessage());
|
||||
|
||||
// Send message on Enter
|
||||
chatInput.addEventListener('keypress', (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
sendMessage();
|
||||
}
|
||||
});
|
||||
|
||||
// Clear chat
|
||||
if (clearBtn) {
|
||||
clearBtn.addEventListener('click', () => {
|
||||
const chatMessages = document.getElementById('chatMessages');
|
||||
if (chatMessages) {
|
||||
chatMessages.innerHTML = `
|
||||
<div class="message bot">
|
||||
<p>Hallo! Ich bin Ihr KI-Assistent. Wie kann ich Ihnen helfen?</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function sendMessage() {
|
||||
const chatInput = document.getElementById('chatInput');
|
||||
const chatMessages = document.getElementById('chatMessages');
|
||||
|
||||
if (!chatInput || !chatMessages) return;
|
||||
|
||||
const message = chatInput.value.trim();
|
||||
if (!message) return;
|
||||
|
||||
// Add user message
|
||||
addChatMessage(message, 'user');
|
||||
chatInput.value = '';
|
||||
|
||||
// Show typing indicator
|
||||
const typingId = showTypingIndicator();
|
||||
|
||||
try {
|
||||
// Send to chat webhook (if configured)
|
||||
const webhookUrl = DASHBOARD_CONFIG.customerData?.chatWebhook;
|
||||
|
||||
if (webhookUrl && webhookUrl !== 'https://sb-demo.userman.de/webhook/rag-chat-webhook/chat') {
|
||||
const response = await fetch(webhookUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
chatInput: message,
|
||||
sessionId: getSessionId(),
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
removeTypingIndicator(typingId);
|
||||
addChatMessage(data.output || data.response || 'Keine Antwort erhalten', 'bot');
|
||||
} else {
|
||||
// Demo response
|
||||
await new Promise(resolve => setTimeout(resolve, 1500));
|
||||
removeTypingIndicator(typingId);
|
||||
|
||||
const demoResponses = [
|
||||
'Das ist eine Demo-Antwort. Laden Sie Dokumente hoch, um echte Antworten zu erhalten.',
|
||||
'Ich kann Ihnen helfen, sobald Sie Ihre Wissensdatenbank mit PDFs gefüllt haben.',
|
||||
'Bitte laden Sie zunächst einige Dokumente hoch, damit ich Ihre Fragen beantworten kann.',
|
||||
];
|
||||
|
||||
addChatMessage(demoResponses[Math.floor(Math.random() * demoResponses.length)], 'bot');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Chat error:', error);
|
||||
removeTypingIndicator(typingId);
|
||||
addChatMessage('Entschuldigung, es gab einen Fehler. Bitte versuchen Sie es erneut.', 'bot');
|
||||
}
|
||||
}
|
||||
|
||||
function addChatMessage(text, type) {
|
||||
const chatMessages = document.getElementById('chatMessages');
|
||||
if (!chatMessages) return;
|
||||
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = `message ${type}`;
|
||||
messageDiv.innerHTML = `<p>${escapeHtml(text)}</p>`;
|
||||
|
||||
chatMessages.appendChild(messageDiv);
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
}
|
||||
|
||||
function showTypingIndicator() {
|
||||
const chatMessages = document.getElementById('chatMessages');
|
||||
if (!chatMessages) return null;
|
||||
|
||||
const id = 'typing-' + Date.now();
|
||||
const typingDiv = document.createElement('div');
|
||||
typingDiv.className = 'message bot typing';
|
||||
typingDiv.id = id;
|
||||
typingDiv.innerHTML = `
|
||||
<span class="typing-indicator">
|
||||
<span></span><span></span><span></span>
|
||||
</span>
|
||||
`;
|
||||
|
||||
chatMessages.appendChild(typingDiv);
|
||||
chatMessages.scrollTop = chatMessages.scrollHeight;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
function removeTypingIndicator(id) {
|
||||
if (!id) return;
|
||||
const typingDiv = document.getElementById(id);
|
||||
if (typingDiv) typingDiv.remove();
|
||||
}
|
||||
|
||||
function getSessionId() {
|
||||
let sessionId = sessionStorage.getItem('chat_session_id');
|
||||
if (!sessionId) {
|
||||
sessionId = 'session-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);
|
||||
sessionStorage.setItem('chat_session_id', sessionId);
|
||||
}
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Embed Code
|
||||
// ============================================
|
||||
function copyEmbedCode() {
|
||||
const embedCode = document.getElementById('embedCode');
|
||||
if (!embedCode) return;
|
||||
|
||||
const text = embedCode.textContent;
|
||||
copyToClipboard('embedCode');
|
||||
|
||||
// Show success message
|
||||
const copySuccess = document.getElementById('copySuccess');
|
||||
if (copySuccess) {
|
||||
copySuccess.style.display = 'flex';
|
||||
setTimeout(() => {
|
||||
copySuccess.style.display = 'none';
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
function copyToClipboard(elementId) {
|
||||
const element = document.getElementById(elementId);
|
||||
if (!element) return;
|
||||
|
||||
const text = element.textContent;
|
||||
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
showNotification('In Zwischenablage kopiert', 'success');
|
||||
}).catch(err => {
|
||||
console.error('Copy failed:', err);
|
||||
// Fallback
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(textarea);
|
||||
showNotification('In Zwischenablage kopiert', 'success');
|
||||
});
|
||||
}
|
||||
|
||||
// Make functions available globally
|
||||
window.copyEmbedCode = copyEmbedCode;
|
||||
window.copyToClipboard = copyToClipboard;
|
||||
|
||||
// ============================================
|
||||
// Settings
|
||||
// ============================================
|
||||
function saveSettings() {
|
||||
const primaryColor = document.getElementById('primaryColor')?.value;
|
||||
const botName = document.getElementById('botName')?.value;
|
||||
const welcomeMessage = document.getElementById('welcomeMessage')?.value;
|
||||
|
||||
// Save to localStorage (in production, save to API)
|
||||
const settings = {
|
||||
primaryColor,
|
||||
botName,
|
||||
welcomeMessage,
|
||||
};
|
||||
|
||||
localStorage.setItem('botkonzept_settings', JSON.stringify(settings));
|
||||
showNotification('Einstellungen gespeichert', 'success');
|
||||
}
|
||||
|
||||
// Make saveSettings available globally
|
||||
window.saveSettings = saveSettings;
|
||||
|
||||
// ============================================
|
||||
// Utility Functions
|
||||
// ============================================
|
||||
function showNotification(message, type = 'info') {
|
||||
// Create notification element
|
||||
const notification = document.createElement('div');
|
||||
notification.className = `notification ${type}`;
|
||||
notification.innerHTML = `
|
||||
<i class="fas fa-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-circle' : 'info-circle'}"></i>
|
||||
<span>${message}</span>
|
||||
`;
|
||||
|
||||
// Add styles
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
padding: 16px 24px;
|
||||
background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#6366f1'};
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||||
z-index: 9999;
|
||||
animation: slideIn 0.3s ease;
|
||||
`;
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
// Remove after 3 seconds
|
||||
setTimeout(() => {
|
||||
notification.style.animation = 'slideOut 0.3s ease';
|
||||
setTimeout(() => notification.remove(), 300);
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
return new Intl.DateTimeFormat('de-DE', {
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric'
|
||||
}).format(date);
|
||||
}
|
||||
|
||||
function formatFileSize(bytes) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = text;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
// Add notification animations
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
from {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
468
js/main.js
Normal file
468
js/main.js
Normal file
@@ -0,0 +1,468 @@
|
||||
/**
|
||||
* BotKonzept - Main JavaScript
|
||||
* ============================
|
||||
* Handles all interactive functionality for the BotKonzept website
|
||||
*/
|
||||
|
||||
// Configuration
|
||||
const CONFIG = {
|
||||
// API Endpoints - Update these for production
|
||||
WEBHOOK_URL: 'https://n8n.userman.de/webhook/botkonzept-registration',
|
||||
API_BASE_URL: 'https://api.botkonzept.de',
|
||||
|
||||
// Validation
|
||||
MIN_NAME_LENGTH: 2,
|
||||
MAX_NAME_LENGTH: 50,
|
||||
|
||||
// Animation
|
||||
SCROLL_OFFSET: 100,
|
||||
ANIMATION_DELAY: 100,
|
||||
};
|
||||
|
||||
// ============================================
|
||||
// DOM Ready
|
||||
// ============================================
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initNavigation();
|
||||
initMobileMenu();
|
||||
initSmoothScroll();
|
||||
initFAQ();
|
||||
initRegistrationForm();
|
||||
initScrollAnimations();
|
||||
initTypingAnimation();
|
||||
});
|
||||
|
||||
// ============================================
|
||||
// Navigation
|
||||
// ============================================
|
||||
function initNavigation() {
|
||||
const navbar = document.getElementById('navbar');
|
||||
let lastScroll = 0;
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const currentScroll = window.pageYOffset;
|
||||
|
||||
// Add shadow on scroll
|
||||
if (currentScroll > 50) {
|
||||
navbar.style.boxShadow = '0 4px 6px -1px rgb(0 0 0 / 0.1)';
|
||||
} else {
|
||||
navbar.style.boxShadow = 'none';
|
||||
}
|
||||
|
||||
// Hide/show navbar on scroll (optional)
|
||||
// if (currentScroll > lastScroll && currentScroll > 200) {
|
||||
// navbar.style.transform = 'translateY(-100%)';
|
||||
// } else {
|
||||
// navbar.style.transform = 'translateY(0)';
|
||||
// }
|
||||
|
||||
lastScroll = currentScroll;
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Mobile Menu
|
||||
// ============================================
|
||||
function initMobileMenu() {
|
||||
const mobileMenuBtn = document.getElementById('mobileMenuBtn');
|
||||
const navLinks = document.getElementById('navLinks');
|
||||
|
||||
if (!mobileMenuBtn || !navLinks) return;
|
||||
|
||||
mobileMenuBtn.addEventListener('click', () => {
|
||||
navLinks.classList.toggle('active');
|
||||
|
||||
// Toggle icon
|
||||
const icon = mobileMenuBtn.querySelector('i');
|
||||
if (navLinks.classList.contains('active')) {
|
||||
icon.classList.remove('fa-bars');
|
||||
icon.classList.add('fa-times');
|
||||
} else {
|
||||
icon.classList.remove('fa-times');
|
||||
icon.classList.add('fa-bars');
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu when clicking a link
|
||||
navLinks.querySelectorAll('a').forEach(link => {
|
||||
link.addEventListener('click', () => {
|
||||
navLinks.classList.remove('active');
|
||||
const icon = mobileMenuBtn.querySelector('i');
|
||||
icon.classList.remove('fa-times');
|
||||
icon.classList.add('fa-bars');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Smooth Scroll
|
||||
// ============================================
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
const targetId = this.getAttribute('href');
|
||||
|
||||
if (targetId === '#') return;
|
||||
|
||||
const targetElement = document.querySelector(targetId);
|
||||
if (targetElement) {
|
||||
const navbarHeight = document.getElementById('navbar').offsetHeight;
|
||||
const targetPosition = targetElement.offsetTop - navbarHeight - 20;
|
||||
|
||||
window.scrollTo({
|
||||
top: targetPosition,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// FAQ Accordion
|
||||
// ============================================
|
||||
function initFAQ() {
|
||||
const faqItems = document.querySelectorAll('.faq-item');
|
||||
|
||||
faqItems.forEach(item => {
|
||||
const question = item.querySelector('.faq-question');
|
||||
|
||||
question.addEventListener('click', () => {
|
||||
// Close other items
|
||||
faqItems.forEach(otherItem => {
|
||||
if (otherItem !== item && otherItem.classList.contains('active')) {
|
||||
otherItem.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle current item
|
||||
item.classList.toggle('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Registration Form
|
||||
// ============================================
|
||||
function initRegistrationForm() {
|
||||
const form = document.getElementById('registerForm');
|
||||
const submitBtn = document.getElementById('submitBtn');
|
||||
const formSuccess = document.getElementById('formSuccess');
|
||||
const formError = document.getElementById('formError');
|
||||
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
// Validate form
|
||||
if (!validateForm(form)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Show loading state
|
||||
setLoadingState(submitBtn, true);
|
||||
|
||||
// Collect form data
|
||||
const formData = {
|
||||
firstName: form.firstName.value.trim(),
|
||||
lastName: form.lastName.value.trim(),
|
||||
email: form.email.value.trim(),
|
||||
company: form.company.value.trim() || null,
|
||||
website: form.website.value.trim() || null,
|
||||
newsletter: form.newsletter.checked,
|
||||
timestamp: new Date().toISOString(),
|
||||
source: 'website',
|
||||
userAgent: navigator.userAgent,
|
||||
language: navigator.language,
|
||||
};
|
||||
|
||||
try {
|
||||
// Send registration request
|
||||
const response = await fetch(CONFIG.WEBHOOK_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
// Show success message
|
||||
form.style.display = 'none';
|
||||
formSuccess.style.display = 'block';
|
||||
|
||||
// Track conversion (if analytics is set up)
|
||||
trackConversion('registration_complete', formData);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Registration error:', error);
|
||||
|
||||
// Show error message
|
||||
form.style.display = 'none';
|
||||
formError.style.display = 'block';
|
||||
|
||||
const errorMessage = document.getElementById('errorMessage');
|
||||
if (errorMessage) {
|
||||
errorMessage.textContent = getErrorMessage(error);
|
||||
}
|
||||
} finally {
|
||||
setLoadingState(submitBtn, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Form validation
|
||||
function validateForm(form) {
|
||||
let isValid = true;
|
||||
|
||||
// Clear previous errors
|
||||
form.querySelectorAll('.error').forEach(el => el.classList.remove('error'));
|
||||
form.querySelectorAll('.error-message').forEach(el => el.remove());
|
||||
|
||||
// Validate first name
|
||||
const firstName = form.firstName.value.trim();
|
||||
if (firstName.length < CONFIG.MIN_NAME_LENGTH) {
|
||||
showFieldError(form.firstName, 'Bitte geben Sie Ihren Vornamen ein');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// Validate last name
|
||||
const lastName = form.lastName.value.trim();
|
||||
if (lastName.length < CONFIG.MIN_NAME_LENGTH) {
|
||||
showFieldError(form.lastName, 'Bitte geben Sie Ihren Nachnamen ein');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// Validate email
|
||||
const email = form.email.value.trim();
|
||||
if (!isValidEmail(email)) {
|
||||
showFieldError(form.email, 'Bitte geben Sie eine gültige E-Mail-Adresse ein');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// Validate website (if provided)
|
||||
const website = form.website.value.trim();
|
||||
if (website && !isValidURL(website)) {
|
||||
showFieldError(form.website, 'Bitte geben Sie eine gültige URL ein (z.B. https://beispiel.de)');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// Validate privacy checkbox
|
||||
if (!form.privacy.checked) {
|
||||
showFieldError(form.privacy, 'Bitte akzeptieren Sie die Datenschutzerklärung');
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// Show field error
|
||||
function showFieldError(field, message) {
|
||||
field.classList.add('error');
|
||||
field.style.borderColor = '#ef4444';
|
||||
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.className = 'error-message';
|
||||
errorDiv.style.color = '#ef4444';
|
||||
errorDiv.style.fontSize = '0.75rem';
|
||||
errorDiv.style.marginTop = '4px';
|
||||
errorDiv.textContent = message;
|
||||
|
||||
field.parentNode.appendChild(errorDiv);
|
||||
}
|
||||
|
||||
// Email validation
|
||||
function isValidEmail(email) {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
// URL validation
|
||||
function isValidURL(url) {
|
||||
try {
|
||||
new URL(url);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Set loading state
|
||||
function setLoadingState(button, isLoading) {
|
||||
const btnText = button.querySelector('.btn-text');
|
||||
const btnLoading = button.querySelector('.btn-loading');
|
||||
|
||||
if (isLoading) {
|
||||
button.disabled = true;
|
||||
if (btnText) btnText.style.display = 'none';
|
||||
if (btnLoading) btnLoading.style.display = 'inline-flex';
|
||||
} else {
|
||||
button.disabled = false;
|
||||
if (btnText) btnText.style.display = 'inline';
|
||||
if (btnLoading) btnLoading.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Get user-friendly error message
|
||||
function getErrorMessage(error) {
|
||||
if (error.message.includes('Failed to fetch')) {
|
||||
return 'Verbindungsfehler. Bitte überprüfen Sie Ihre Internetverbindung.';
|
||||
}
|
||||
if (error.message.includes('500')) {
|
||||
return 'Serverfehler. Bitte versuchen Sie es später erneut.';
|
||||
}
|
||||
if (error.message.includes('400')) {
|
||||
return 'Ungültige Eingabe. Bitte überprüfen Sie Ihre Daten.';
|
||||
}
|
||||
return 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.';
|
||||
}
|
||||
|
||||
// Reset form
|
||||
function resetForm() {
|
||||
const form = document.getElementById('registerForm');
|
||||
const formSuccess = document.getElementById('formSuccess');
|
||||
const formError = document.getElementById('formError');
|
||||
|
||||
if (form) {
|
||||
form.reset();
|
||||
form.style.display = 'flex';
|
||||
}
|
||||
if (formSuccess) formSuccess.style.display = 'none';
|
||||
if (formError) formError.style.display = 'none';
|
||||
}
|
||||
|
||||
// Make resetForm available globally
|
||||
window.resetForm = resetForm;
|
||||
|
||||
// ============================================
|
||||
// Scroll Animations
|
||||
// ============================================
|
||||
function initScrollAnimations() {
|
||||
const animatedElements = document.querySelectorAll('.feature-card, .step, .pricing-card, .faq-item');
|
||||
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, index) => {
|
||||
if (entry.isIntersecting) {
|
||||
setTimeout(() => {
|
||||
entry.target.classList.add('visible');
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
}, index * CONFIG.ANIMATION_DELAY);
|
||||
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.1,
|
||||
rootMargin: '0px 0px -50px 0px'
|
||||
});
|
||||
|
||||
animatedElements.forEach(el => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateY(20px)';
|
||||
el.style.transition = 'opacity 0.5s ease, transform 0.5s ease';
|
||||
observer.observe(el);
|
||||
});
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Typing Animation (Chat Preview)
|
||||
// ============================================
|
||||
function initTypingAnimation() {
|
||||
const typingMessage = document.querySelector('.message.typing');
|
||||
if (!typingMessage) return;
|
||||
|
||||
// Simulate typing response
|
||||
setTimeout(() => {
|
||||
typingMessage.innerHTML = '<p>Sie können Ihre Bestellung ganz einfach über unser Online-Formular aufgeben. Alternativ können Sie uns auch telefonisch unter 0800-123456 erreichen.</p>';
|
||||
typingMessage.classList.remove('typing');
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Analytics & Tracking
|
||||
// ============================================
|
||||
function trackConversion(eventName, data = {}) {
|
||||
// Google Analytics 4
|
||||
if (typeof gtag !== 'undefined') {
|
||||
gtag('event', eventName, {
|
||||
'event_category': 'conversion',
|
||||
'event_label': 'registration',
|
||||
...data
|
||||
});
|
||||
}
|
||||
|
||||
// Facebook Pixel
|
||||
if (typeof fbq !== 'undefined') {
|
||||
fbq('track', 'Lead', data);
|
||||
}
|
||||
|
||||
// Console log for debugging
|
||||
console.log('Conversion tracked:', eventName, data);
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Utility Functions
|
||||
// ============================================
|
||||
|
||||
// Debounce function
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return function executedFunction(...args) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
// Throttle function
|
||||
function throttle(func, limit) {
|
||||
let inThrottle;
|
||||
return function(...args) {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Format currency
|
||||
function formatCurrency(amount, currency = 'EUR') {
|
||||
return new Intl.NumberFormat('de-DE', {
|
||||
style: 'currency',
|
||||
currency: currency
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
// Format date
|
||||
function formatDate(date) {
|
||||
return new Intl.DateTimeFormat('de-DE', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
}).format(new Date(date));
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Export for testing
|
||||
// ============================================
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
validateForm,
|
||||
isValidEmail,
|
||||
isValidURL,
|
||||
formatCurrency,
|
||||
formatDate
|
||||
};
|
||||
}
|
||||
75
logo/20250119_Logo_Botkozept.svg
Normal file
75
logo/20250119_Logo_Botkozept.svg
Normal file
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Creator: CorelDRAW -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="359px" height="60px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||
viewBox="0 0 2150 359"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.fil1 {fill:#FEFEFE;fill-rule:nonzero}
|
||||
.fil4 {fill:#88CED7;fill-rule:nonzero}
|
||||
.fil3 {fill:#4FC0EF;fill-rule:nonzero}
|
||||
.fil2 {fill:#3A7ABD;fill-rule:nonzero}
|
||||
.fil0 {fill:#234182;fill-rule:nonzero}
|
||||
]]>
|
||||
</style>
|
||||
</defs>
|
||||
<g id="Bot_x0020_TV">
|
||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||
<g id="_1548485603296">
|
||||
<g>
|
||||
<path class="fil0" d="M204 168l0 22c0,8 5,14 12,14 3,0 6,-2 9,-4 2,-3 4,-6 4,-10l0 -22c0,-8 -5,-14 -12,-14 -3,0 -6,2 -9,4 -2,3 -4,6 -4,10z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="fil0" d="M142 168l0 22c0,8 5,14 12,14 3,0 6,-2 9,-4 2,-3 4,-6 4,-10l0 -22c0,-8 -5,-14 -12,-14 -3,0 -6,2 -9,4 -2,3 -4,6 -4,10z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="_1548485603200">
|
||||
<g>
|
||||
<path class="fil1" d="M209 192l2 0c1,0 1,0 1,-1l0 -24c0,-1 0,-1 -1,-1l-2 0c-1,0 -1,0 -1,1l0 24c0,1 0,1 1,1z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path class="fil1" d="M147 192l2 0c1,0 1,0 1,-1l0 -24c0,-1 0,-1 -1,-1l-2 0c-1,0 -1,0 -1,1l0 24c0,1 0,1 1,1z"/>
|
||||
</g>
|
||||
</g>
|
||||
<path class="fil0" d="M119 24l0 32 -38 0 0 -32c0,-10 8,-19 19,-19 10,0 19,8 19,19zm221 259l-221 0 0 56c0,10 -8,19 -18,20 -11,1 -20,-8 -20,-19l0 -219 0 -8 47 0c-5,0 -8,3 -9,8 0,1 0,1 0,2l0 113c0,5 4,9 9,9l211 0c10,0 19,8 20,18 1,11 -8,20 -19,20z"/>
|
||||
<g id="_1548485605696">
|
||||
<path class="fil2" d="M251 302l38 0 0 38c0,10 -8,19 -19,19 -10,0 -19,-8 -19,-19l0 -38z"/>
|
||||
</g>
|
||||
<g id="_1548485607712">
|
||||
<path class="fil3" d="M359 94c0,10 -8,19 -19,19l-32 0 0 -38 32 0c10,0 19,8 19,19z"/>
|
||||
</g>
|
||||
<g id="_1548485606320">
|
||||
<path class="fil4" d="M19 245l43 0 0 38 -43 0c-10,0 -19,-8 -19,-19 0,-10 8,-19 19,-19z"/>
|
||||
</g>
|
||||
<path class="fil2" d="M251 237l0 -2 0 -112c0,-5 -4,-9 -9,-9l-222 0c-10,0 -19,-8 -20,-18 -1,-11 8,-20 19,-20l232 0 0 -55c0,-11 9,-20 20,-19 10,1 18,9 18,20l0 217 0 8 -47 0c4,0 8,-3 9,-8 0,0 0,-1 0,-1z"/>
|
||||
<path class="fil0" d="M391 213l0 -212 90 0c40,0 60,16 60,49 0,24 -13,41 -39,52 28,5 42,21 42,48 0,42 -22,63 -66,63l-87 0zm86 -22c25,0 38,-13 38,-38 0,-25 -17,-37 -51,-37l-12 0 0 -18c40,-5 61,-20 61,-44 0,-20 -11,-30 -34,-30l-60 0 0 167 58 0z"/>
|
||||
<path id="_1" class="fil0" d="M609 107c0,57 26,86 77,86 51,0 76,-29 76,-86 0,-56 -25,-85 -76,-85 -52,0 -77,28 -77,85zm-29 1c0,-72 35,-108 106,-108 70,0 105,36 105,108 0,71 -35,107 -105,107 -71,0 -106,-36 -106,-107z"/>
|
||||
<polygon id="_2" class="fil0" points="977,1 977,24 910,24 910,213 883,213 883,24 816,24 816,1 "/>
|
||||
<path id="_3" class="fil0" d="M1037 1l0 212 -27 0 0 -212 27 0zm149 0l-95 100 97 112 -38 0 -86 -102 0 -17 88 -93 35 0z"/>
|
||||
<path id="_4" class="fil0" d="M1216 107c0,57 26,86 77,86 51,0 76,-29 76,-86 0,-56 -25,-85 -76,-85 -52,0 -77,28 -77,85zm-29 1c0,-72 35,-108 106,-108 70,0 105,36 105,108 0,71 -35,107 -105,107 -71,0 -106,-36 -106,-107z"/>
|
||||
<polygon id="_5" class="fil0" points="1594,1 1594,24 1468,191 1592,191 1592,213 1435,213 1435,191 1565,24 1438,24 1438,1 "/>
|
||||
<polygon id="_6" class="fil0" points="1777,1 1777,24 1666,24 1666,95 1771,95 1771,117 1666,117 1666,191 1779,191 1779,213 1638,213 1638,1 "/>
|
||||
<path id="_7" class="fil0" d="M1820 213l0 -212 86 0c43,0 65,19 65,57 0,41 -30,66 -89,75l-6 -23c43,-6 65,-23 65,-51 0,-24 -13,-35 -38,-35l-56 0 0 189 -27 0z"/>
|
||||
<polygon id="_8" class="fil0" points="2150,1 2150,24 2083,24 2083,213 2056,213 2056,24 1989,24 1989,1 "/>
|
||||
<polygon class="fil2" points="391,359 391,254 411,254 446,333 481,254 500,254 500,359 482,359 482,286 454,359 437,359 409,286 409,359 "/>
|
||||
<polygon id="_1_8" class="fil2" points="593,254 593,271 541,271 541,297 591,297 591,315 541,315 541,342 594,342 594,359 522,359 522,254 "/>
|
||||
<path id="_2_9" class="fil2" d="M653 342c22,0 32,-13 32,-38 0,-22 -11,-32 -32,-32l-21 0 0 71 21 0zm-41 17l0 -104 41 0c34,0 52,16 52,49 0,37 -17,55 -52,55l-41 0z"/>
|
||||
<polygon id="_3_10" class="fil2" points="740,254 740,359 721,359 721,254 "/>
|
||||
<polygon id="_4_11" class="fil2" points="773,359 753,359 797,254 818,254 863,359 842,359 830,330 796,330 802,313 823,313 807,274 "/>
|
||||
<polygon id="_5_12" class="fil2" points="876,359 876,254 896,254 931,333 966,254 985,254 985,359 967,359 967,286 939,359 922,359 893,286 893,359 "/>
|
||||
<polygon id="_6_13" class="fil2" points="1078,254 1078,271 1026,271 1026,297 1076,297 1076,315 1026,315 1026,342 1079,342 1079,359 1007,359 1007,254 "/>
|
||||
<polygon id="_7_14" class="fil2" points="1165,254 1165,271 1135,271 1135,359 1116,359 1116,271 1086,271 1086,254 "/>
|
||||
<polygon id="_8_15" class="fil2" points="1251,254 1251,271 1196,342 1251,342 1251,359 1174,359 1174,342 1232,271 1176,271 1176,254 "/>
|
||||
<polygon id="_9" class="fil2" points="1332,359 1332,254 1352,254 1407,330 1407,254 1425,254 1425,359 1406,359 1351,281 1351,359 "/>
|
||||
<polygon id="_10" class="fil2" points="1518,254 1518,271 1466,271 1466,297 1516,297 1516,315 1466,315 1466,342 1519,342 1519,359 1447,359 1447,254 "/>
|
||||
<polygon id="_11" class="fil2" points="1605,254 1605,271 1576,271 1576,359 1556,359 1556,271 1526,271 1526,254 "/>
|
||||
<polygon id="_12" class="fil2" points="1608,254 1628,254 1639,329 1666,254 1684,254 1710,326 1721,254 1740,254 1721,359 1703,359 1674,277 1643,359 1625,359 "/>
|
||||
<path id="_13" class="fil2" d="M1770 306c0,24 11,36 32,36 21,0 31,-12 31,-36 0,-24 -10,-36 -31,-36 -22,0 -32,12 -32,36zm-20 0c0,-35 17,-53 52,-53 34,0 51,18 51,53 0,35 -17,53 -51,53 -33,0 -51,-18 -52,-53z"/>
|
||||
<path id="_14" class="fil2" d="M1872 358l0 -104 47 0c21,0 32,9 32,28 0,13 -8,23 -25,31l33 45 -24 0 -32 -45 0 -9c18,-3 28,-10 28,-21 0,-8 -4,-12 -13,-12l-26 0 0 87 -20 0z"/>
|
||||
<path id="_15" class="fil2" d="M1988 254l0 104 -19 0 0 -104 19 0zm73 0l-44 49 49 56 -27 0 -40 -49 0 -13 39 -43 24 0z"/>
|
||||
<path id="_16" class="fil2" d="M2071 354l0 -17c10,4 22,6 35,6 16,0 24,-5 24,-16 0,-8 -5,-12 -15,-12l-16 0c-21,0 -32,-10 -32,-29 0,-21 15,-32 46,-32 12,0 23,2 33,5l0 17c-10,-4 -21,-6 -33,-6 -17,0 -26,5 -26,15 0,8 4,12 13,12l16 0c23,0 34,10 34,29 0,22 -14,33 -43,33 -13,0 -25,-2 -35,-5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.3 KiB |
Reference in New Issue
Block a user