"use client"; import React, { useState } from 'react'; import { Button } from "@/components/ui/button"; import { CheckCircle, Calendar, Mail, ArrowLeft } from "lucide-react"; import { supabase } from '@/lib/supabase'; import { colors } from '@/lib/colors'; import AppointmentForm from './AppointmentForm'; import EmailVerification from './EmailVerification'; import { useAuth } from '@/hooks/useAuth'; type BookingStep = 'form' | 'verification' | 'success'; interface AppointmentData { name: string; telefon: string; firma: string; email: string; beschreibung: string; termin_datum?: Date; termin_time?: string; } export default function AppointmentBooking() { const { user } = useAuth(); const [currentStep, setCurrentStep] = useState('form'); const [appointmentData, setAppointmentData] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [testMode, setTestMode] = useState(false); // Production mode - no test indicators const [tableStructure, setTableStructure] = useState([]); const [productionMode, setProductionMode] = useState(false); // Enable email verification const [customerAction, setCustomerAction] = useState<'created' | 'updated' | null>(null); const handleFormSubmit = async (data: AppointmentData) => { setAppointmentData(data); // Always go to email verification step setCurrentStep('verification'); }; const handleVerificationComplete = async () => { if (!appointmentData) return; // Prüfe Authentifizierung nach E-Mail-Bestätigung if (!user) { setError('Bitte bestätige zuerst deine E-Mail-Adresse, um den Termin zu speichern.'); return; } setLoading(true); setError(null); try { // Create the appointment datetime by combining date and time console.log('=== DATE PROCESSING DEBUG ==='); console.log('Input termin_datum:', appointmentData.termin_datum); console.log('Input termin_time:', appointmentData.termin_time); console.log('Input termin_datum type:', typeof appointmentData.termin_datum); console.log('Input termin_datum instanceof Date:', appointmentData.termin_datum instanceof Date); // Check if termin_datum is actually a Date object if (!(appointmentData.termin_datum instanceof Date)) { console.error('❌ termin_datum is not a Date object!'); setError('Fehler: Ungültiges Datum. Bitte wählen Sie einen Termin aus.'); return; } const appointmentDateTime = new Date(appointmentData.termin_datum); console.log('Created appointmentDateTime:', appointmentDateTime); console.log('appointmentDateTime.toISOString():', appointmentDateTime.toISOString()); const [hours] = appointmentData.termin_time!.split(':').map(Number); console.log('Extracted hours:', hours); // Create the appointment datetime in local time to avoid timezone issues const year = appointmentDateTime.getFullYear(); const month = appointmentDateTime.getMonth(); const day = appointmentDateTime.getDate(); console.log('Date components:', { year, month, day, hours }); // Create the final appointment datetime in local time const finalAppointmentDateTime = new Date(year, month, day, hours, 0, 0, 0); console.log('Final appointmentDateTime (local):', finalAppointmentDateTime); console.log('Final appointmentDateTime.toISOString():', finalAppointmentDateTime.toISOString()); console.log('Final appointmentDateTime.getTime():', finalAppointmentDateTime.getTime()); console.log('Final appointmentDateTime local string:', finalAppointmentDateTime.toLocaleString('de-DE')); // Store the appointment time in local time format const localTimeString = `${year}-${(month + 1).toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}T${hours.toString().padStart(2, '0')}:00:00`; console.log('Local time string to save:', localTimeString); // Check if customer already exists (by email) console.log('=== CUSTOMER CHECK DEBUG ==='); console.log('Input email:', appointmentData.email); console.log('Input email type:', typeof appointmentData.email); console.log('Input email length:', appointmentData.email.length); console.log('Input email trimmed:', appointmentData.email.trim()); console.log('Input email lowercase:', appointmentData.email.trim().toLowerCase()); // First, let's check what's in the database for this email await checkSpecificEmail(appointmentData.email); // Try multiple email variations to find existing customer const emailVariations = [ appointmentData.email.trim(), appointmentData.email.trim().toLowerCase(), appointmentData.email.trim().toUpperCase() ]; console.log('Checking email variations:', emailVariations); let existingCustomers: any[] = []; let checkError: any = null; // Try each email variation for (const emailVariation of emailVariations) { const { data, error } = await supabase .from('kunden_projekte') .select('*') .eq('email', emailVariation) .order('erstellt_am', { ascending: false }); if (error) { console.error(`Error checking email variation "${emailVariation}":`, error); checkError = error; continue; } if (data && data.length > 0) { console.log(`Found ${data.length} customers with email "${emailVariation}"`); existingCustomers = data; break; } } console.log('Database query result:', { existingCustomers, checkError }); console.log('Number of existing customers found:', existingCustomers?.length || 0); if (existingCustomers && existingCustomers.length > 0) { console.log('All found customers with this email:'); existingCustomers.forEach((customer, index) => { console.log(`${index + 1}. ID: ${customer.id}, Email: "${customer.email}", Created: ${customer.erstellt_am}, Termin: ${customer.termin_datum}`); }); } if (checkError) { console.error('Error checking existing customer:', checkError); setError('Fehler beim Überprüfen der Kundendaten. Bitte versuchen Sie es erneut.'); return; } const existingCustomer = existingCustomers && existingCustomers.length > 0 ? existingCustomers[0] : null; if (existingCustomer) { console.log('✅ Existing customer found:', existingCustomer); console.log('Will UPDATE existing customer with ID:', existingCustomer.id); // Warn if there are multiple entries with the same email if (existingCustomers.length > 1) { console.warn(`⚠️ Found ${existingCustomers.length} entries with email ${appointmentData.email}. Using the most recent one.`); } } else { console.log('❌ No existing customer found - will CREATE new'); } const appointmentDataToSave = { email: appointmentData.email, beschreibung: `${appointmentData.beschreibung}\n\nTermin: ${formatAppointmentDate(appointmentData.termin_datum!, appointmentData.termin_time!)}\n\nKontakt: ${appointmentData.name} (${appointmentData.telefon})\nFirma: ${appointmentData.firma}`, termin_datum: localTimeString, // Store in local time format ansprechpartner_name: appointmentData.name, telefon: appointmentData.telefon, firma: appointmentData.firma, berater: 'Webklar Team', zielgruppe: 'Terminanfrage' }; let result; if (existingCustomer) { // Use upsert to ensure we update the existing customer console.log('🔄 Starting UPSERT operation for customer ID:', existingCustomer.id); const newDescription = `${existingCustomer.beschreibung || ''}\n\n--- NEUER TERMIN ---\n${appointmentDataToSave.beschreibung}`; console.log('New description:', newDescription); // Use upsert with the existing ID to force update const { data: upsertData, error: upsertError } = await supabase .from('kunden_projekte') .upsert({ id: existingCustomer.id, // Use existing ID to force update ...appointmentDataToSave, beschreibung: newDescription, erstellt_am: new Date().toISOString() }, { onConflict: 'id' // Update on ID conflict }) .select('*'); if (upsertError) { console.error('❌ Error upserting customer:', upsertError); setError('Fehler beim Aktualisieren der Kundendaten. Bitte versuchen Sie es erneut.'); return; } if (!upsertData || upsertData.length === 0) { console.error('❌ Upsert operation returned no data'); setError('Fehler beim Aktualisieren der Kundendaten. Bitte versuchen Sie es erneut.'); return; } result = upsertData[0]; console.log('✅ Customer updated via upsert:', result); // Verify the update by fetching the customer again const { data: verifyData, error: verifyError } = await supabase .from('kunden_projekte') .select('*') .eq('id', existingCustomer.id) .single(); if (verifyError) { console.warn('⚠️ Could not verify update:', verifyError); } else { console.log('✅ Update verified - customer data:', verifyData); } setCustomerAction('updated'); } else { // Create new customer record ONLY if no existing customer found console.log('🆕 Starting CREATE operation for new customer'); console.log('Create data:', appointmentDataToSave); const { data, error } = await supabase .from('kunden_projekte') .insert(appointmentDataToSave) .select('*'); if (error) { console.error('❌ Error creating customer:', error); setError('Fehler beim Erstellen der Kundendaten. Bitte versuchen Sie es erneut.'); return; } if (!data || data.length === 0) { console.error('❌ Create operation returned no data'); setError('Fehler beim Erstellen der Kundendaten. Bitte versuchen Sie es erneut.'); return; } result = data[0]; // Get the first (and only) created record console.log('✅ Customer created successfully:', result); setCustomerAction('created'); } setCurrentStep('success'); } catch (err) { console.error('Unexpected error saving appointment:', err); setError('Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.'); } finally { setLoading(false); } }; const handleBack = () => { setCurrentStep('form'); setError(null); }; const handleReset = () => { setCurrentStep('form'); setAppointmentData(null); setError(null); setLoading(false); setCustomerAction(null); }; const testDatabaseConnection = async () => { setLoading(true); setError(null); try { // Test basic connection and get table structure const { data, error } = await supabase .from('kunden_projekte') .select('*') .limit(1); if (error) { console.error('Database connection test failed:', error); setError(`Datenbank-Verbindung fehlgeschlagen: ${error.message}`); return; } console.log('Database connection successful:', data); const columns = Object.keys(data[0] || {}); console.log('Table structure:', columns); setTableStructure(columns); // Analyze which columns we can use const availableColumns = { email: columns.includes('email'), description: columns.includes('description') || columns.includes('beschreibung'), termin_datum: columns.includes('termin_datum'), name: columns.includes('name') || columns.includes('ansprechpartn'), phone: columns.includes('phone') || columns.includes('telefon'), company: columns.includes('company') || columns.includes('firma') }; console.log('Available columns for appointment:', availableColumns); let statusMessage = '✅ Datenbank-Verbindung erfolgreich!\n\n'; statusMessage += '📋 Verfügbare Spalten:\n'; Object.entries(availableColumns).forEach(([key, available]) => { statusMessage += `${available ? '✅' : '❌'} ${key}\n`; }); setError(statusMessage); } catch (err) { console.error('Connection test error:', err); setError('❌ Datenbank-Verbindung fehlgeschlagen'); } finally { setLoading(false); } }; const cleanupDuplicateCustomers = async () => { setLoading(true); setError(null); try { // Find all customers with duplicate emails const { data: allCustomers, error } = await supabase .from('kunden_projekte') .select('*') .order('erstellt_am', { ascending: true }); if (error) { console.error('Error fetching customers:', error); setError('Fehler beim Laden der Kundendaten.'); return; } // Group by email const emailGroups: { [email: string]: any[] } = {}; allCustomers?.forEach(customer => { if (!emailGroups[customer.email]) { emailGroups[customer.email] = []; } emailGroups[customer.email].push(customer); }); // Find duplicates const duplicates = Object.entries(emailGroups) .filter(([email, customers]) => customers.length > 1) .map(([email, customers]) => ({ email, customers })); console.log('Found duplicate customers:', duplicates); if (duplicates.length === 0) { setError('✅ Keine Duplikate gefunden!'); return; } let statusMessage = `🔍 ${duplicates.length} E-Mail-Adressen mit Duplikaten gefunden:\n\n`; duplicates.forEach(({ email, customers }) => { statusMessage += `📧 ${email}: ${customers.length} Einträge\n`; customers.forEach((customer, index) => { statusMessage += ` ${index + 1}. ID: ${customer.id} (${customer.erstellt_am})\n`; }); statusMessage += '\n'; }); statusMessage += '💡 Tipp: Der neueste Eintrag wird für neue Termine verwendet.'; setError(statusMessage); } catch (err) { console.error('Cleanup error:', err); setError('Fehler beim Bereinigen der Duplikate.'); } finally { setLoading(false); } }; const checkSpecificEmail = async (email: string) => { console.log('🔍 Checking specific email:', email); const { data, error } = await supabase .from('kunden_projekte') .select('*') .eq('email', email) .order('erstellt_am', { ascending: false }); if (error) { console.error('Error checking email:', error); return; } console.log(`Found ${data?.length || 0} entries for email "${email}":`); data?.forEach((entry, index) => { console.log(`${index + 1}. ID: ${entry.id}, Email: "${entry.email}", Created: ${entry.erstellt_am}`); }); return data; }; const formatAppointmentDate = (date: Date, time: string) => { return new Intl.DateTimeFormat('de-DE', { weekday: 'long', day: '2-digit', month: '2-digit', year: 'numeric' }).format(date) + ` um ${time} Uhr`; }; const cleanupIncorrectDates = async () => { setLoading(true); setError(null); try { console.log('🧹 Cleaning up incorrect appointment dates...'); // Find all entries with the incorrect date "2025-07-21 07:00:00" const { data: incorrectEntries, error: findError } = await supabase .from('kunden_projekte') .select('*') .eq('termin_datum', '2025-07-21T07:00:00.000Z'); if (findError) { console.error('Error finding incorrect entries:', findError); setError('Fehler beim Finden der fehlerhaften Einträge.'); return; } console.log(`Found ${incorrectEntries?.length || 0} entries with incorrect date`); if (incorrectEntries && incorrectEntries.length > 0) { // Update all incorrect entries to remove the termin_datum const { error: updateError } = await supabase .from('kunden_projekte') .update({ termin_datum: null }) .eq('termin_datum', '2025-07-21T07:00:00.000Z'); if (updateError) { console.error('Error updating incorrect entries:', updateError); setError('Fehler beim Bereinigen der fehlerhaften Einträge.'); return; } console.log('✅ Successfully cleaned up incorrect appointment dates'); alert(`✅ ${incorrectEntries.length} fehlerhafte Termine wurden bereinigt!`); } else { console.log('No incorrect entries found'); alert('✅ Keine fehlerhaften Termine gefunden!'); } } catch (err) { console.error('Unexpected error cleaning up dates:', err); setError('Ein unerwarteter Fehler ist aufgetreten.'); } finally { setLoading(false); } }; return (
{/* Production Mode Indicator */} {productionMode && (

Terminbuchung aktiv: Ihre Termine werden direkt in unserem System gespeichert.

)} {/* Enhanced Step Indicator */}
{/* Step 1 */}
Termin auswählen
{/* Connector 1 */}
{/* Step 2 */}
E-Mail bestätigen
{/* Error Display */} {error && (
{error}
)} {/* Step Content */} {currentStep === 'form' && ( )} {currentStep === 'verification' && appointmentData && ( )} {currentStep === 'success' && appointmentData && (

Termin bestätigt!

{customerAction === 'created' ? 'Vielen Dank für Ihre erste Terminanfrage! Ihr Kundenprofil wurde erstellt.' : 'Vielen Dank für Ihre weitere Terminanfrage! Ihr bestehendes Kundenprofil wurde aktualisiert.' }

Ihr Termin:

{formatAppointmentDate(appointmentData.termin_datum!, appointmentData.termin_time!)}

Kontaktdaten:

{appointmentData.name}
{appointmentData.firma}
{appointmentData.email}

Vielen Dank für Ihre Terminanfrage! Wir werden uns in Kürze bei Ihnen melden, um den Termin zu bestätigen.

)}
); }