diff --git a/EMAIL_SETUP.md b/EMAIL_SETUP.md new file mode 100644 index 0000000..f03f5e4 --- /dev/null +++ b/EMAIL_SETUP.md @@ -0,0 +1,55 @@ +# E-Mail Setup für Unternehmensanmeldungen + +## Aktuelle Lösung + +Die Formular-Daten werden derzeit in der Browser-Konsole geloggt. Um E-Mails an `knuth.timo@gmail.com` zu senden, haben Sie mehrere Optionen: + +## Option 1: EmailJS (Empfohlen - Kostenlos) + +1. Gehen Sie zu [https://www.emailjs.com/](https://www.emailjs.com/) +2. Erstellen Sie ein kostenloses Konto +3. Verbinden Sie Ihren Gmail-Account +4. Erstellen Sie eine E-Mail-Vorlage +5. Ersetzen Sie die Platzhalter in `src/lib/emailService.ts`: + +```typescript +service_id: 'Ihr_Service_ID', +template_id: 'Ihr_Template_ID', +user_id: 'Ihr_User_ID' +``` + +## Option 2: Webhook.site (Einfach) + +1. Gehen Sie zu [https://webhook.site/](https://webhook.site/) +2. Kopieren Sie die Webhook-URL +3. Ersetzen Sie `'https://webhook.site/your-webhook-url'` in `src/lib/emailService.ts` +4. Die Daten werden an die Webhook-URL gesendet + +## Option 3: Zapier (Automatisierung) + +1. Erstellen Sie ein Zapier-Konto +2. Erstellen Sie einen "Webhook" Trigger +3. Verbinden Sie ihn mit Gmail +4. Verwenden Sie die Webhook-URL in der Anwendung + +## Option 4: Netlify Forms (Wenn auf Netlify gehostet) + +Fügen Sie `netlify` zu den Form-Attributen hinzu: + +```html +
+``` + +## Aktuelle Implementierung + +Die Daten werden derzeit in der Browser-Konsole ausgegeben. Öffnen Sie die Entwicklertools (F12) und schauen Sie in die Konsole, um die Formular-Daten zu sehen. + +## PostHog Tracking + +Die folgenden Events werden getrackt: +- `company_registration_started` - Formular wird abgesendet +- `company_registration_completed` - Erfolgreiche Übermittlung +- `company_registration_failed` - Fehler bei der Übermittlung +- `experience_selected` - Erfahrungslevel ausgewählt +- `energy_type_selected` - Energieart ausgewählt +- `service_selected` - Service ausgewählt diff --git a/EMAIL_SOLUTION.md b/EMAIL_SOLUTION.md new file mode 100644 index 0000000..6c88a21 --- /dev/null +++ b/EMAIL_SOLUTION.md @@ -0,0 +1,84 @@ +# E-Mail-Lösung für Unternehmensanmeldungen + +## Problem +Webhook.site empfängt nur HTTP-Requests, aber leitet keine E-Mails weiter. + +## Lösung: EmailJS (Kostenlos & Einfach) + +### Schritt 1: EmailJS Account erstellen +1. Gehen Sie zu [https://www.emailjs.com/](https://www.emailjs.com/) +2. Klicken Sie auf "Sign Up" (kostenlos) +3. Erstellen Sie ein Konto + +### Schritt 2: E-Mail-Service einrichten +1. **Dashboard** → **Email Services** → **Add New Service** +2. Wählen Sie **Gmail** +3. Verbinden Sie Ihr Gmail-Konto (`knuth.timo@gmail.com`) +4. Notieren Sie sich die **Service ID** (z.B. `service_xxxxxxx`) + +### Schritt 3: E-Mail-Vorlage erstellen +1. **Dashboard** → **Email Templates** → **Create New Template** +2. **Template ID:** `template_company_registration` +3. **Subject:** `Neue Unternehmensanmeldung - EnergieProfis` +4. **Content:** +``` +Neue Unternehmensanmeldung + +Firmenname: {{company_name}} +Ansprechpartner: {{contact_person}} +E-Mail: {{email}} +Telefon: {{phone}} +Website: {{website}} +PLZ: {{zip_code}} +Stadt: {{city}} +Energiearten: {{energy_types}} +Leistungen: {{services}} +Jahre Erfahrung: {{experience}} +Einzugsgebiet: {{coverage_area}} +Kontaktpräferenz: {{contact_preference}} +Newsletter: {{newsletter}} + +Unternehmensbeschreibung: +{{description}} +``` + +### Schritt 4: User ID finden +1. **Dashboard** → **Account** → **General** +2. Kopieren Sie Ihre **Public Key** (User ID) + +### Schritt 5: Code aktualisieren +Ersetzen Sie in `src/lib/emailService.ts`: +```typescript +user_id: 'YOUR_EMAILJS_USER_ID' // Mit Ihrer echten User ID +``` + +## Alternative: Zapier (Automatisiert) + +### Schritt 1: Zapier Account +1. Gehen Sie zu [https://zapier.com](https://zapier.com) +2. Erstellen Sie ein kostenloses Konto + +### Schritt 2: Zap erstellen +1. **Create Zap** +2. **Trigger:** "Webhooks by Zapier" → "Catch Hook" +3. **Action:** "Gmail" → "Send Email" +4. **Konfiguration:** + - **To:** `knuth.timo@gmail.com` + - **Subject:** `Neue Unternehmensanmeldung - EnergieProfis` + - **Body:** Verwenden Sie die Webhook-Daten + +### Schritt 3: Webhook-URL ersetzen +Ersetzen Sie die Webhook-URL in `src/lib/emailService.ts` mit der Zapier-URL. + +## Sofortige Lösung: Console Logging + +Bis Sie einen E-Mail-Service einrichten, werden alle Daten in der Browser-Konsole geloggt: +1. Öffnen Sie F12 (Entwicklertools) +2. Gehen Sie zum "Console" Tab +3. Alle Formular-Daten werden dort angezeigt + +## Status +✅ **Webhook funktioniert** - Daten werden empfangen +⚠️ **E-Mail-Weiterleitung** - Benötigt E-Mail-Service +✅ **PostHog Analytics** - Funktioniert +✅ **Dropdown ohne Animation** - Funktioniert diff --git a/POSTHOG_SETUP.md b/POSTHOG_SETUP.md new file mode 100644 index 0000000..b341fbe --- /dev/null +++ b/POSTHOG_SETUP.md @@ -0,0 +1,81 @@ +# PostHog Analytics Setup + +PostHog has been successfully integrated into the Energie Finder Profi project. + +## Configuration + +- **API Key**: `phc_jIkj0hQSY670vRaUVjSRSDOqmLCDGkL6GJy44iqE84M` +- **Host**: `https://app.posthog.com` +- **Initialization**: PostHog is automatically initialized in `main.tsx` + +## Files Added/Modified + +1. **`src/lib/posthog.ts`** - PostHog configuration and initialization +2. **`src/hooks/usePostHog.ts`** - React hook for easy PostHog usage +3. **`src/main.tsx`** - PostHog initialization on app start +4. **`src/components/HeroSection.tsx`** - Example tracking implementation +5. **`package.json`** - Added posthog-js dependency + +## Usage + +### Basic Event Tracking + +```tsx +import { usePostHog } from '@/hooks/usePostHog' + +const MyComponent = () => { + const posthog = usePostHog() + + const handleClick = () => { + posthog.capture('button_clicked', { + button_name: 'search', + page: 'home' + }) + } + + return +} +``` + +### User Identification + +```tsx +const posthog = usePostHog() + +// Identify a user +posthog.identify('user_123', { + email: 'user@example.com', + name: 'John Doe' +}) +``` + +### Feature Flags + +```tsx +const posthog = usePostHog() + +// Check if feature is enabled +const isNewFeatureEnabled = posthog.isFeatureEnabled('new_feature') + +// Get feature flag value +const featureValue = posthog.getFeatureFlag('feature_with_value') +``` + +## Environment Variables + +You can optionally set the PostHog API key via environment variable: + +```env +VITE_POSTHOG_API_KEY=phc_jIkj0hQSY670vRaUVjSRSDOqmLCDGkL6GJy44iqE84M +``` + +## Current Tracking + +The following events are currently being tracked: + +- `hero_search_clicked` - When user clicks "Installateur Finden" in hero section +- `hero_view_all_clicked` - When user clicks "Alle Installateure Ansehen" + +## PostHog Dashboard + +Visit [https://app.posthog.com](https://app.posthog.com) to view analytics data, create funnels, and set up feature flags. diff --git a/package-lock.json b/package-lock.json index d1422b3..4780341 100644 --- a/package-lock.json +++ b/package-lock.json @@ -47,6 +47,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.462.0", "next-themes": "^0.3.0", + "posthog-js": "^1.200.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", @@ -988,6 +989,12 @@ "node": ">=18" } }, + "node_modules/@posthog/core": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@posthog/core/-/core-1.0.2.tgz", + "integrity": "sha512-hWk3rUtJl2crQK0WNmwg13n82hnTwB99BT99/XI5gZSvIlYZ1TPmMZE8H2dhJJ98J/rm9vYJ/UXNzw3RV5HTpQ==", + "license": "MIT" + }, "node_modules/@radix-ui/number": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", @@ -3724,6 +3731,17 @@ "dev": true, "license": "MIT" }, + "node_modules/core-js": { + "version": "3.45.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.1.tgz", + "integrity": "sha512-L4NPsJlCfZsPeXukyzHFlg/i7IIVwHSItR0wg0FLNqYClJ4MQYTYLbC7EkjKYRLZF2iof2MUgN0EGy7MdQFChg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -4327,6 +4345,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.4.8", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz", + "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -5801,6 +5825,41 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, + "node_modules/posthog-js": { + "version": "1.261.7", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.261.7.tgz", + "integrity": "sha512-Fjpbz6VfIMsEbKIN/UyTWhU1DGgVIngqoRjPGRolemIMOVzTfI77OZq8WwiBhMug+rU+wNhGCQhC41qRlR5CxA==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "@posthog/core": "1.0.2", + "core-js": "^3.38.1", + "fflate": "^0.4.8", + "preact": "^10.19.3", + "web-vitals": "^4.2.4" + }, + "peerDependencies": { + "@rrweb/types": "2.0.0-alpha.17", + "rrweb-snapshot": "2.0.0-alpha.17" + }, + "peerDependenciesMeta": { + "@rrweb/types": { + "optional": true + }, + "rrweb-snapshot": { + "optional": true + } + } + }, + "node_modules/preact": { + "version": "10.27.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.1.tgz", + "integrity": "sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -7314,6 +7373,12 @@ } } }, + "node_modules/web-vitals": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz", + "integrity": "sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==", + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 10b9297..80cb2cb 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "input-otp": "^1.4.2", "lucide-react": "^0.462.0", "next-themes": "^0.3.0", + "posthog-js": "^1.200.0", "react": "^18.3.1", "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", diff --git a/src/App.tsx b/src/App.tsx index abb4d61..7163373 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,9 @@ import Wind from "./pages/Wind"; import InstallateurFinden from "./pages/InstallateurFinden"; import KostenloseBeratung from "./pages/KostenloseBeratung"; import UnternehmenListen from "./pages/UnternehmenListen"; +import Impressum from "./pages/Impressum"; +import Datenschutz from "./pages/Datenschutz"; +import CookieEinstellungen from "./pages/CookieEinstellungen"; import NotFound from "./pages/NotFound"; const queryClient = new QueryClient(); @@ -26,6 +29,9 @@ const App = () => ( } /> } /> } /> + } /> + } /> + } /> {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} } /> diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index c21873b..3c2a273 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -19,7 +19,7 @@ const Footer = () => { return (