"use client"; import { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Textarea } from '@/components/ui/textarea'; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; import { Calculator, ChevronDown, ChevronUp, Loader2, Info, HelpCircle } from 'lucide-react'; import { colors } from '@/lib/colors'; interface PriceCalculatorProps { onPriceCalculated?: (price: string, details: string) => void; } const services = [ { id: 'seo', label: 'SEO-Optimierung', tooltip: 'Suchmaschinenoptimierung für bessere Sichtbarkeit in Google & Co.' }, { id: 'database', label: 'Datenbank-Anbindung', tooltip: 'Verbindung zu bestehenden Datenbanken oder neue Datenbankstrukturen' }, { id: 'ai', label: 'KI-Integration', tooltip: 'Künstliche Intelligenz für Chatbots, Empfehlungssysteme oder Automatisierung' }, { id: 'responsive', label: 'Responsives Design', tooltip: 'Optimale Darstellung auf allen Geräten: Desktop, Tablet, Smartphone' }, { id: 'social', label: 'Social-Media-Verknüpfung', tooltip: 'Integration von Social Media Feeds und Sharing-Funktionen' }, { id: 'payment', label: 'Zahlungsmethoden', tooltip: 'Sichere Online-Zahlungen mit PayPal, Kreditkarte, SEPA & Co.' }, { id: 'analytics', label: 'Nutzeranalyse & Tracking', tooltip: 'Google Analytics, Conversion-Tracking und detaillierte Besucherstatistiken' }, { id: 'domain', label: 'Domainverwaltung', tooltip: 'Professionelle Domain-Einrichtung und DNS-Konfiguration' }, { id: 'strategy', label: 'Strategieberatung', tooltip: 'Digitale Strategie, Zielgruppenanalyse und Wettbewerbsanalyse' }, { id: 'app', label: 'App-Entwicklung', tooltip: 'Native oder Progressive Web Apps für iOS und Android' } ]; const subscriptionServices = [ { id: 'content', label: 'Content-Pflege', tooltip: 'Regelmäßige Aktualisierung von Texten, Bildern und Inhalten' }, { id: 'newsletter', label: 'Newsletter-Versand & Pflege', tooltip: 'Professionelle Newsletter-Erstellung, Versand und Analyse' }, { id: 'landingpage', label: 'Landingpage-Erstellung (1x/Monat)', tooltip: 'Conversion-optimierte Landingpages für Kampagnen und Aktionen' }, { id: 'blog', label: 'Blog-Pflege', tooltip: 'Regelmäßige Blogartikel, SEO-Optimierung und Community-Management' }, { id: 'domain_redirects', label: 'Domainverwaltung & Umleitungen', tooltip: 'Professionelle Domain-Verwaltung, Weiterleitungen und DNS-Management' } ]; export default function PriceCalculator({ onPriceCalculated }: PriceCalculatorProps) { const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); const [formData, setFormData] = useState({ pages: 1, services: [] as string[], express: false, subscription: [] as string[], specialRequirements: '' }); const [result, setResult] = useState<{ price: string; details: string } | null>(null); const handleServiceChange = (serviceId: string, checked: boolean) => { setFormData(prev => ({ ...prev, services: checked ? [...prev.services, serviceId] : prev.services.filter(id => id !== serviceId) })); }; const handleSubscriptionChange = (serviceId: string, checked: boolean) => { setFormData(prev => ({ ...prev, subscription: checked ? [...prev.subscription, serviceId] : prev.subscription.filter(id => id !== serviceId) })); }; const generatePrompt = () => { const selectedServices = services.filter(service => formData.services.includes(service.id)); const selectedSubscriptions = subscriptionServices.filter(service => formData.subscription.includes(service.id)); const additionalServices = selectedServices.length > 0 ? selectedServices.map(s => s.label).join(', ') : 'Keine zusätzlichen Leistungen ausgewählt'; const ongoingServices = selectedSubscriptions.length > 0 ? selectedSubscriptions.map(s => s.label).join(', ') : 'Keine laufenden Services ausgewählt'; return `Du bist eine intelligente Webprojekt-KI, die Kunden bei der Preisabschätzung für professionelle Websites unterstützt. Analysiere die vom Kunden angegebenen Wünsche und gib einen geschätzten Preisrahmen in Euro aus, basierend auf Komplexität, Umfang und Zusatzleistungen. Wichtige Regeln: – Die Basiswebsite beginnt bei 300 € – Mehr Seiten erhöhen den Preis moderat – Express-Lieferung kostet +30 % Aufpreis – Je mehr Leistungen ausgewählt werden, desto effizienter kann gearbeitet werden ⇒ kleine Mengenrabatte möglich – Laufende Services bedeuten monatliche Zusatzkosten (nicht im Grundpreis enthalten) – Alle Preise sind unverbindliche Schätzungen Ziel: Der Kunde soll eine ehrliche und transparente Einschätzung bekommen – nicht zu hoch, aber auch nicht unter Wert. ⸻ Kundeneingaben Seitenanzahl: ${formData.pages} Zusätzliche Leistungen: ${additionalServices} Laufende Services: ${ongoingServices} Express-Lieferung gewünscht? ${formData.express ? 'Ja' : 'Nein'} Besondere Wünsche / Anforderungen: ${formData.specialRequirements || 'Keine besonderen Wünsche angegeben'} ⸻ Bitte liefere als Antwort: – Eine realistische Preisspanne in Euro (z. B. 750–950 €) – Eine kurze Begründung (1–2 Sätze) – Hinweis auf Beratungsgespräch für verbindliches Angebot`; }; const calculateLocalPrice = () => { let basePrice = 300; // Basis-Website // Preis pro Seite (ab der 2. Seite) if (formData.pages > 1) { basePrice += (formData.pages - 1) * 50; } // Zusatzleistungen const selectedServices = services.filter(service => formData.services.includes(service.id)); const servicePrices = { 'seo': 150, 'database': 200, 'ai': 300, 'responsive': 100, 'social': 80, 'payment': 120, 'analytics': 90, 'domain': 60, 'strategy': 180, 'app': 400 }; let servicesCost = 0; selectedServices.forEach(service => { servicesCost += servicePrices[service.id as keyof typeof servicePrices] || 0; }); // Mengenrabatt für mehrere Leistungen if (selectedServices.length > 2) { servicesCost *= 0.9; // 10% Rabatt ab 3 Leistungen } // Express-Lieferung let totalPrice = basePrice + servicesCost; if (formData.express) { totalPrice *= 1.3; // +30% für Express } // Preisspanne (10% Variation) const variation = totalPrice * 0.1; const minPrice = Math.round(totalPrice - variation); const maxPrice = Math.round(totalPrice + variation); return { price: `${minPrice}–${maxPrice}€`, details: `Basierend auf ${formData.pages} Seiten und ${selectedServices.length} Zusatzleistungen. ${formData.express ? 'Express-Lieferung inklusive.' : ''}` }; }; const calculatePrice = async () => { setIsLoading(true); try { const prompt = generatePrompt(); console.log('Sending API request with prompt:', prompt); const response = await fetch('/api/calculate-price', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: prompt }) }); console.log('Response status:', response.status); if (!response.ok) { const errorText = await response.text(); console.error('API Error Response:', errorText); // Fallback zur lokalen Preisberechnung console.log('Using local price calculation as fallback'); const localResult = calculateLocalPrice(); setResult(localResult); onPriceCalculated?.(localResult.price, localResult.details); return; } const data = await response.json(); console.log('API Response data:', data); const aiResponse = data.choices?.[0]?.message?.content || data.choices?.[0]?.text || 'Preis konnte nicht berechnet werden'; console.log('AI Response:', aiResponse); // Extract price range and details const priceMatch = aiResponse.match(/(\d+[-–]\d+€)/); const price = priceMatch ? priceMatch[1] : 'Preis auf Anfrage'; const details = aiResponse.replace(priceMatch?.[0] || '', '').trim(); const result = { price, details }; setResult(result); onPriceCalculated?.(price, details); } catch (error) { console.error('Error calculating price:', error); // Fallback zur lokalen Preisberechnung console.log('Using local price calculation as fallback due to error'); const localResult = calculateLocalPrice(); setResult(localResult); onPriceCalculated?.(localResult.price, localResult.details); } finally { setIsLoading(false); } }; return (
{/* Upper section with light background */}

Kalkuliere deinen individuellen Preis mit wenigen Klicks

{/* Anzahl Seiten - Slider */}
setFormData(prev => ({ ...prev, pages: parseInt(e.target.value) }))} className="flex-1 h-3 rounded-lg appearance-none cursor-pointer" style={{ background: `linear-gradient(to right, ${colors.secondary} 0%, ${colors.secondary} ${(formData.pages - 1) * 11.11}%, ${colors.tertiary} ${(formData.pages - 1) * 11.11}%, ${colors.tertiary} 100%)` }} /> {formData.pages}
1 10
{/* Leistungen */}
{services.map((service) => (
handleServiceChange(service.id, checked as boolean)} className="w-5 h-5" />

{service.tooltip}

))}
{/* Express-Lieferung */}
setFormData(prev => ({ ...prev, express: checked as boolean }))} className="w-5 h-5" />
{/* Laufende Services */}
{subscriptionServices.map((service) => (
handleSubscriptionChange(service.id, checked as boolean)} className="w-5 h-5" />

{service.tooltip}

))}
{/* Wave transition */}
{/* Lower section with darker background */}
{/* Individuelle Wünsche */}