'use client'; import React, { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import * as z from 'zod'; import { Form, FormField, FormItem, FormLabel, FormControl, FormDescription, FormMessage, } from '@/components/ui/form'; import { Input } from '@/components/ui/input'; import { Textarea } from '@/components/ui/textarea'; import { Switch } from '@/components/ui/switch'; import { supabase } from '@/lib/supabaseClient'; const steps = [ { title: 'Unternehmen & Zielgruppe' }, { title: 'Ziel der Website' }, { title: 'Inhalte & Struktur' }, { title: 'Design & Stil' }, { title: 'Technische Funktionen' }, { title: 'Pflege & Support' }, { title: 'Projektzeit & Ansprechpartner' }, { title: 'Kommunikation & Zusammenarbeit' }, ]; const webseitenZieleOptions = [ 'Neukunden', 'Vertrauen', 'Produkte erklären', 'Online verkaufen', 'Terminbuchung', 'anderes', ]; const geplanteSeitenOptions = [ 'Start', 'Über uns', 'Leistungen', 'Referenzen', 'Kontakt', 'Impressum', 'Datenschutz', 'Blog', 'Karriere', 'FAQ', 'Sonstiges', ]; const stilrichtungOptions = [ 'modern', 'klassisch', 'verspielt', 'minimalistisch', 'technisch', 'kreativ', 'seriös', 'freundlich', 'exklusiv', 'andere', ]; const funktionenOptions = [ 'Kontaktformular', 'Shop', 'Terminbuchung', 'Newsletter', 'Blog', 'Kalender', 'Benutzerverwaltung', 'andere', ]; const drittanbieterOptions = [ 'Stripe', 'Supabase', 'Google Ads', 'Google Analytics', 'Mailchimp', 'andere', ]; const kommunikationswegOptions = [ 'E-Mail', 'Telefon', 'WhatsApp', 'Videocall', ]; // Zod schema for all steps (fields optional, step validation below) const fullSchema = z.object({ // Step 1 firma: z.string().min(1, 'Pflichtfeld'), beschreibung: z.string().min(1, 'Pflichtfeld'), zielgruppe: z.string().min(1, 'Pflichtfeld'), website_vorhanden: z.boolean(), stilvorbilder: z.string().optional(), was_gefaellt_gefaellt_nicht: z.string().optional(), // Step 2 ziel_der_website: z.array(z.string()).min(1, 'Bitte mindestens ein Ziel auswählen'), // Step 3 seiten_geplant: z.array(z.string()).min(1, 'Mindestens eine Seite angeben'), texte_bilder_vorhanden: z.boolean(), fokus_inhalte: z.string().optional(), // Step 4 logo_farben_vorhanden: z.boolean(), design_wunsch: z.string().min(1, 'Bitte Stilrichtung wählen'), beispiellinks: z.string().optional(), // Step 5 features_gewuenscht: z.array(z.string()).min(1, 'Mindestens eine Funktion wählen'), drittanbieter: z.array(z.string()).optional(), // Step 6 selbst_pflegen: z.boolean(), laufende_betreuung: z.boolean(), // Step 7 deadline: z.string().min(1, 'Bitte Datum wählen'), projekt_verantwortlich: z.string().min(1, 'Pflichtfeld'), budget: z.string().optional(), // Step 8 kommunikationsweg: z.array(z.string()).min(1, 'Mindestens einen Weg wählen'), feedback_geschwindigkeit: z.string().optional(), }); type FullFormType = z.infer; const stepFieldMap: Record = { 0: [ 'firma', 'beschreibung', 'zielgruppe', 'website_vorhanden', 'stilvorbilder', 'was_gefaellt_gefaellt_nicht', ], 1: ['ziel_der_website'], 2: ['seiten_geplant', 'texte_bilder_vorhanden', 'fokus_inhalte'], 3: ['logo_farben_vorhanden', 'design_wunsch', 'beispiellinks'], 4: ['features_gewuenscht', 'drittanbieter'], 5: ['selbst_pflegen', 'laufende_betreuung'], 6: ['deadline', 'projekt_verantwortlich', 'budget'], 7: ['kommunikationsweg', 'feedback_geschwindigkeit'], }; export default function CustomerStepperForm() { const [currentStep, setCurrentStep] = useState(0); const [isSubmitting, setIsSubmitting] = useState(false); const [submitSuccess, setSubmitSuccess] = useState(false); const [submitError, setSubmitError] = useState(null); const methods = useForm({ resolver: zodResolver(fullSchema), defaultValues: { firma: '', beschreibung: '', zielgruppe: '', website_vorhanden: false, stilvorbilder: '', was_gefaellt_gefaellt_nicht: '', ziel_der_website: [], seiten_geplant: [], texte_bilder_vorhanden: false, fokus_inhalte: '', logo_farben_vorhanden: false, design_wunsch: '', beispiellinks: '', features_gewuenscht: [], drittanbieter: [], selbst_pflegen: false, laufende_betreuung: false, deadline: '', projekt_verantwortlich: '', budget: '', kommunikationsweg: [], feedback_geschwindigkeit: '', }, mode: 'onChange', }); async function nextStep() { // Validate only fields for this step const fields = stepFieldMap[currentStep]; const valid = await methods.trigger(fields as any); if (valid) setCurrentStep((s) => Math.min(s + 1, steps.length - 1)); } function prevStep() { setCurrentStep((s) => Math.max(s - 1, 0)); } async function handleSubmitAll() { setIsSubmitting(true); setSubmitError(null); try { const data = methods.getValues(); console.log('Form data:', data); // Convert arrays to comma-separated strings for Supabase const processedData = { ...data, // Convert checkbox arrays to comma-separated strings ziel_der_website: Array.isArray(data.ziel_der_website) ? data.ziel_der_website.join(', ') : data.ziel_der_website, seiten_geplant: Array.isArray(data.seiten_geplant) ? data.seiten_geplant.join(', ') : data.seiten_geplant, features_gewuenscht: Array.isArray(data.features_gewuenscht) ? data.features_gewuenscht.join(', ') : data.features_gewuenscht, drittanbieter: Array.isArray(data.drittanbieter) ? data.drittanbieter.join(', ') : data.drittanbieter, kommunikationsweg: Array.isArray(data.kommunikationsweg) ? data.kommunikationsweg.join(', ') : data.kommunikationsweg, }; console.log('Processed data for Supabase:', processedData); const { error } = await supabase.from('kunden_projekte').insert([processedData]); if (error) { console.error('Supabase error:', error); setSubmitError('Fehler beim Speichern: ' + error.message); } else { setSubmitSuccess(true); } } catch (e: any) { console.error('Unexpected error:', e); setSubmitError('Unbekannter Fehler: ' + (e.message || e.toString())); } finally { setIsSubmitting(false); } } return (
{/* Stepper Progress */}
{/* Desktop Stepper - Horizontal */}
{steps.map((step, idx) => (
{idx + 1}
{step.title} {idx < steps.length - 1 &&
}
))}
{/* Mobile Stepper - Vertical */}
{currentStep + 1}
{steps[currentStep].title}
{/* Mobile Progress Bar */}
{/* Mobile Step Indicator */}
{steps.map((_, idx) => (
))}
{/* Step Content */}
{currentStep === 0 && (
( Unternehmensname * )} /> ( Kurzbeschreibung *