import React, { useState, useEffect } from 'react'; import { Send, CheckCircle, AlertCircle, Globe, Server, Check, ArrowRight, ArrowLeft, User, FileText, Target, Layout, Palette, Zap, Lightbulb, Settings, ClipboardCheck, Lock, Cloud, Upload, Receipt, Building2, Link as LinkIcon, Info, CreditCard, Wallet, Calculator, RefreshCw } from 'lucide-react'; import { Button } from './Button'; import { useAuth } from '../context/AuthContext'; import { Link } from 'react-router-dom'; import { supabase, isSupabaseConfigured } from '../lib/supabaseClient'; import { defaultPlans } from '../lib/defaultPlans'; import { ProductPackage } from '../types'; interface Inspiration { url: string; comment: string; } export const OrderForm: React.FC = () => { const { user, loading } = useAuth(); const [currentStep, setCurrentStep] = useState(1); const [showPaymentSummary, setShowPaymentSummary] = useState(false); const [isSubmitted, setIsSubmitted] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const [submitError, setSubmitError] = useState(null); const [errors, setErrors] = useState([]); const [privacyAccepted, setPrivacyAccepted] = useState(false); const [aszfAccepted, setAszfAccepted] = useState(false); const [availablePackages, setAvailablePackages] = useState(defaultPlans); const totalSteps = 10; const [formData, setFormData] = useState({ name: '', company: '', email: user?.email || '', phone: '', package: 'Pro Web', description: '', goals: [] as string[], goalOther: '', successCriteria: '', content: [] as string[], contentOther: '', existingAssets: 'Nem' as 'Igen' | 'Nem', contentLink: '', primaryColor: '', secondaryColor: '', balanceColor: '', style: [] as string[], targetAudience: '', features: [] as string[], inspirations: [ { url: '', comment: '' }, { url: '', comment: '' }, { url: '', comment: '' } ] as Inspiration[], extras: [] as string[], domainName: '', notes: '', // Számlázási Mezők billingType: 'individual' as 'individual' | 'company', billingName: '', billingZip: '', billingCity: '', billingAddress: '', taxNumber: '' }); const colorOptions = [ { name: 'Piros', value: '#ef4444' }, { name: 'Kék', value: '#3b82f6' }, { name: 'Zöld', value: '#22c55e' }, { name: 'Lila', value: '#a855f7' }, { name: 'Fekete', value: '#171717' }, { name: 'Fehér', value: '#ffffff' }, { name: 'Szürke', value: '#6b7280' }, { name: 'Narancs', value: '#f97316' }, { name: 'Sárga', value: '#eab308' }, { name: 'Türkiz', value: '#14b8a6' }, { name: 'Barna', value: '#78350f' }, ]; const styleOptions = [ 'Modern és letisztult', 'Üzleti és professzionális', 'Fiatalos és energikus', 'Spirituális / nyugodt', 'Természetes / barátságos', 'Luxus / prémium' ]; const steps = [ { id: 1, title: 'Kapcsolat', icon: User }, { id: 2, title: 'Bemutatkozás', icon: FileText }, { id: 3, title: 'Célok', icon: Target }, { id: 4, title: 'Tartalom', icon: Layout }, { id: 5, title: 'Design', icon: Palette }, { id: 6, title: 'Funkciók', icon: Zap }, { id: 7, title: 'Inspirációk', icon: Lightbulb }, { id: 8, title: 'Extrák', icon: Settings }, { id: 9, title: 'Számlázás', icon: Receipt }, { id: 10, title: 'Összegzés', icon: ClipboardCheck }, ]; useEffect(() => { const fetchPlans = async () => { if (!isSupabaseConfigured) return; try { const { data } = await supabase.from('plans').select('*'); if (data && data.length > 0) { const sorted = [...data].sort((a, b) => { const priceA = a.is_custom_price ? Infinity : (a.total_price || 0); const priceB = b.is_custom_price ? Infinity : (b.total_price || 0); return priceA - priceB; }); setAvailablePackages(sorted); } } catch (e) { console.error("Error fetching packages:", e); } }; fetchPlans(); }, []); useEffect(() => { if (user) { setFormData(prev => ({ ...prev, email: user.email || '', name: prev.name || `${user.user_metadata?.last_name || ''} ${user.user_metadata?.first_name || ''}`.trim(), billingName: prev.billingName || `${user.user_metadata?.last_name || ''} ${user.user_metadata?.first_name || ''}`.trim() })); } }, [user]); const selectedPkg = availablePackages.find(p => p.name === formData.package); const totalAmount = selectedPkg?.total_price || 0; const advanceAmount = selectedPkg?.advance_price || 0; const remainingAmount = totalAmount - advanceAmount; const isCustomPrice = selectedPkg?.is_custom_price; const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handleCheckboxChange = (category: 'goals' | 'content' | 'style' | 'features' | 'extras', value: string) => { setFormData(prev => { const list = prev[category]; if (list.includes(value)) { return { ...prev, [category]: list.filter(item => item !== value) }; } else { if (category === 'style' && list.length >= 2) return prev; return { ...prev, [category]: [...list, value] }; } }); }; const validateStep = (step: number): boolean => { const newErrors: string[] = []; if (step === 1) { if (!formData.name) newErrors.push('A név megadása kötelező.'); if (!formData.phone) newErrors.push('A telefonszám megadása kötelező.'); } if (step === 9) { if (!formData.billingName) newErrors.push('A számlázási név megadása kötelező.'); if (!formData.billingZip) newErrors.push('Az irányítószám megadása kötelező.'); if (!formData.billingCity) newErrors.push('A város megadása kötelező.'); if (!formData.billingAddress) newErrors.push('A cím megadása kötelező.'); if (formData.billingType === 'company' && !formData.taxNumber) newErrors.push('Cég esetén az adószám kötelező.'); } if (step === 10) { if (!privacyAccepted) newErrors.push('Az adatkezelési tájékoztató elfogadása kötelező.'); if (!aszfAccepted) newErrors.push('Az ÁSZF elfogadása kötelező.'); } setErrors(newErrors); return newErrors.length === 0; }; const nextStep = () => { if (validateStep(currentStep)) { if (currentStep < totalSteps) { setCurrentStep(prev => prev + 1); window.scrollTo({ top: document.getElementById('order-form-container')?.offsetTop || 0, behavior: 'smooth' }); } else { setShowPaymentSummary(true); window.scrollTo({ top: document.getElementById('order-form-container')?.offsetTop || 0, behavior: 'smooth' }); } } }; const prevStep = () => { if (showPaymentSummary) { setShowPaymentSummary(false); return; } if (currentStep > 1) { setCurrentStep(prev => prev - 1); window.scrollTo({ top: document.getElementById('order-form-container')?.offsetTop || 0, behavior: 'smooth' }); } }; const handleSubmit = async () => { setIsSubmitting(true); setSubmitError(null); const amountStr = isCustomPrice ? 'Egyedi árazás' : `${totalAmount.toLocaleString('hu-HU')} Ft`; if (isSupabaseConfigured && user) { try { // 1. Create order const { data: orderData, error } = await supabase.from('orders').insert({ user_id: user.id, customer_name: formData.name, customer_email: formData.email, package: formData.package, status: 'new', amount: amountStr, details: { ...formData, payment_summary: { total: totalAmount, advance: advanceAmount, remaining: remainingAmount, currency: 'HUF', is_custom: isCustomPrice } } }).select().single(); if (error) throw error; // 2. Initiate Stripe Payment if not custom price if (!isCustomPrice && (formData.package === 'Landing Page' || formData.package === 'Pro Web')) { try { const { data: checkoutData, error: checkoutError } = await supabase.functions.invoke('create-checkout-session', { body: { order_id: orderData.id, package_name: formData.package, payment_type: 'deposit', customer_email: formData.email } }); if (checkoutError) throw checkoutError; if (checkoutData?.url) { window.location.href = checkoutData.url; return; // Stop execution to redirect } } catch (stripeErr: any) { console.error("Stripe error:", stripeErr); alert("Rendelés rögzítve, de a fizetési rendszer átmenetileg nem elérhető. Kérjük vegye fel velünk a kapcsolatot."); setIsSubmitted(true); } } else { // Custom price or demo mode setIsSubmitted(true); } } catch (err: any) { setSubmitError('Hiba a rendelés mentésekor: ' + err.message); } finally { setIsSubmitting(false); } } else { // Demo mode fallback await new Promise(r => setTimeout(r, 1000)); setIsSubmitted(true); setIsSubmitting(false); } }; const inputClass = "w-full px-4 py-3 rounded-xl border border-gray-200 bg-white focus:ring-4 focus:ring-primary/10 focus:border-primary outline-none transition-all shadow-sm font-medium text-gray-900"; const labelClass = "text-xs font-black text-gray-400 uppercase tracking-widest mb-2 block ml-1"; const formatPrice = (num: number) => num.toLocaleString('hu-HU') + ' Ft'; if (loading) { return
Betöltés...
; } // Ha nincs bejelentkezve, mutassuk a bejelentkezési felhívást if (!user) { return (

Jelentkezz be a folytatáshoz!

A projekt indításához és a rendelés leadásához kérjük, lépj be fiókodba, vagy regisztrálj egyet pár perc alatt.

); } if (isSubmitted) { return (

Rendelésedet fogadtuk!

Köszönjük a bizalmat! A megadott e-mail címre elküldtük a visszaigazolást. Kollégánk hamarosan felveszi veled a kapcsolatot.

); } return (
{/* Header with Progress */}

Projekt Indítása

{showPaymentSummary ? (isCustomPrice ? 'Utolsó lépés: Véglegesítés' : 'Utolsó lépés: Fizetés') : `Lépés ${currentStep} / ${totalSteps}`}

{!showPaymentSummary && (
{steps.map((s) => ( ))}
)}
{/* Main Content */}
{errors.length > 0 && (
{errors.map((err, idx) =>

{err}

)}
)} {!showPaymentSummary ? (
{currentStep === 1 && (
{availablePackages.map((pkg) => ( ))}
)} {currentStep === 2 && (
)} {currentStep === 3 && (
{['Cég bemutatása', 'Online értékesítés', 'Időpontfoglalás', 'Ügyfélszerzés', 'Információközlés'].map(goal => ( ))}
)} {currentStep === 4 && (
{['Rólunk', 'Szolgáltatások', 'Referenciák', 'Gyakori Kérdések', 'Blog', 'Kapcsolat'].map(item => ( ))}
)} {currentStep === 5 && (

FŐSZÍN

setFormData({...formData, primaryColor: e.target.value})} className="w-full h-12 rounded-xl cursor-pointer bg-white" />

MELLÉKSZÍN

setFormData({...formData, secondaryColor: e.target.value})} className="w-full h-12 rounded-xl cursor-pointer bg-white" />

HÁTTÉRSZÍN

setFormData({...formData, balanceColor: e.target.value})} className="w-full h-12 rounded-xl cursor-pointer bg-white" />
{styleOptions.map(style => ( ))}
)} {currentStep === 6 && (
{['Kapcsolatfelvételi űrlap', 'Hírlevél feliratkozás', 'Kereső funkció', 'Többnyelvűség', 'Admin felület', 'Bankkártyás fizetés'].map(feat => ( ))}
)} {currentStep === 7 && (
{[0, 1, 2].map(i => (

Példa oldal {i+1} linkje

{ const ins = [...formData.inspirations]; ins[i].url = e.target.value; setFormData({...formData, inspirations: ins}); }} placeholder="https://..." className={inputClass} />

Mi tetszik rajta?

{ const ins = [...formData.inspirations]; ins[i].comment = e.target.value; setFormData({...formData, inspirations: ins}); }} placeholder="Színek, elrendezés, stílus..." className={inputClass} />
))}
)} {currentStep === 8 && (
)} {currentStep === 9 && (
{formData.billingType === 'company' &&
}
)} {currentStep === 10 && (

Csomag

{formData.package}

Ügyfél

{formData.name}

Számlázási Cím

{formData.billingZip} {formData.billingCity}, {formData.billingAddress}

)}
) : ( /* PAYMENT SUMMARY / CUSTOM ORDER VIEW */
{isCustomPrice ? ( /* CUSTOM PRICE VIEW */ <>

Rendelés Véglegesítése

Egyedi csomagot választottál. A rendelés leadása után munkatársunk hamarosan felveszi veled a kapcsolatot a pontos igények és az árazás egyeztetése miatt.

Választott Konstrukció

Egyedi Árazás

A "Rendelés Leadása" gombra kattintva rögzítjük igényedet.

) : ( /* STANDARD PAYMENT VIEW */ <>

Rendelés Összesítése

A projekt elindításához kérjük, fizesse be az előleget. A rendszerünk automatikusan értesít minket a befizetésről, és azonnal megkezdjük a munkát.

Projekt Teljes Ára

{formatPrice(totalAmount)}

Fennmaradó (Demó után)

{formatPrice(remainingAmount)}

Jelenleg Fizetendő Előleg

{formatPrice(advanceAmount)}

A gombra kattintva átirányítjuk a biztonságos Stripe fizetési oldalra.

Fontos: A rendszer a rendelés leadása után elküldi Önnek az előlegszámlát is. A bankkártyás fizetés azonnali feldolgozást tesz lehetővé.

)}
)}
{/* Footer Navigation */}
{!showPaymentSummary ? ( ) : ( )}
); };