2025-12-26 14:03:18 +01:00
import React , { useState , useEffect } from 'react' ;
2025-12-21 20:40:32 +01:00
import {
Send , CheckCircle , AlertCircle , Globe , Server , Check ,
ArrowRight , ArrowLeft , User , FileText , Target , Layout ,
Palette , Zap , Lightbulb , Settings , ClipboardCheck , Lock ,
2025-12-26 14:03:18 +01:00
Cloud , Upload , Receipt , Building2 , Link as LinkIcon , Info ,
CreditCard , Wallet , Calculator , RefreshCw
2025-12-21 20:40:32 +01:00
} from 'lucide-react' ;
import { Button } from './Button' ;
import { useAuth } from '../context/AuthContext' ;
import { Link } from 'react-router-dom' ;
import { supabase , isSupabaseConfigured } from '../lib/supabaseClient' ;
2025-12-26 14:03:18 +01:00
import { defaultPlans } from '../lib/defaultPlans' ;
import { ProductPackage } from '../types' ;
2025-12-21 20:40:32 +01:00
interface Inspiration {
url : string ;
comment : string ;
}
export const OrderForm : React.FC = ( ) = > {
const { user , loading } = useAuth ( ) ;
const [ currentStep , setCurrentStep ] = useState ( 1 ) ;
2025-12-26 14:03:18 +01:00
const [ showPaymentSummary , setShowPaymentSummary ] = useState ( false ) ;
2025-12-21 20:40:32 +01:00
const [ isSubmitted , setIsSubmitted ] = useState ( false ) ;
const [ isSubmitting , setIsSubmitting ] = useState ( false ) ;
const [ submitError , setSubmitError ] = useState < string | null > ( null ) ;
const [ errors , setErrors ] = useState < string [ ] > ( [ ] ) ;
const [ privacyAccepted , setPrivacyAccepted ] = useState ( false ) ;
const [ aszfAccepted , setAszfAccepted ] = useState ( false ) ;
2025-12-26 14:03:18 +01:00
const [ availablePackages , setAvailablePackages ] = useState < ProductPackage [ ] > ( defaultPlans ) ;
const totalSteps = 10 ;
2025-12-21 20:40:32 +01:00
const [ formData , setFormData ] = useState ( {
name : '' ,
company : '' ,
email : user?.email || '' ,
phone : '' ,
2025-12-26 14:03:18 +01:00
package : 'Pro Web' ,
2025-12-21 20:40:32 +01:00
description : '' ,
goals : [ ] as string [ ] ,
goalOther : '' ,
successCriteria : '' ,
content : [ ] as string [ ] ,
contentOther : '' ,
2025-12-26 14:03:18 +01:00
existingAssets : 'Nem' as 'Igen' | 'Nem' ,
contentLink : '' ,
2025-12-21 20:40:32 +01:00
primaryColor : '' ,
secondaryColor : '' ,
balanceColor : '' ,
style : [ ] as string [ ] ,
targetAudience : '' ,
features : [ ] as string [ ] ,
inspirations : [
{ url : '' , comment : '' } ,
{ url : '' , comment : '' } ,
{ url : '' , comment : '' }
] as Inspiration [ ] ,
extras : [ ] as string [ ] ,
domainName : '' ,
2025-12-26 14:03:18 +01:00
notes : '' ,
// Számlázási Mezők
billingType : 'individual' as 'individual' | 'company' ,
billingName : '' ,
billingZip : '' ,
billingCity : '' ,
billingAddress : '' ,
taxNumber : ''
2025-12-21 20:40:32 +01:00
} ) ;
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 } ,
2025-12-26 14:03:18 +01:00
{ id : 9 , title : 'Számlázás' , icon : Receipt } ,
{ id : 10 , title : 'Összegzés' , icon : ClipboardCheck } ,
2025-12-21 20:40:32 +01:00
] ;
2025-12-26 14:03:18 +01:00
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 ) ;
2025-12-21 20:40:32 +01:00
}
2025-12-26 14:03:18 +01:00
} catch ( e ) {
console . error ( "Error fetching packages:" , e ) ;
2025-12-21 20:40:32 +01:00
}
} ;
2025-12-26 14:03:18 +01:00
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 ( )
} ) ) ;
}
2025-12-21 20:40:32 +01:00
} , [ user ] ) ;
2025-12-26 14:03:18 +01:00
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 ;
2025-12-21 20:40:32 +01:00
const handleInputChange = ( e : React.ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) = > {
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 {
2025-12-26 14:03:18 +01:00
if ( category === 'style' && list . length >= 2 ) return prev ;
2025-12-21 20:40:32 +01:00
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ő.' ) ;
}
2025-12-26 14:03:18 +01:00
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ő.' ) ;
2025-12-21 20:40:32 +01:00
}
2025-12-26 14:03:18 +01:00
setErrors ( newErrors ) ;
return newErrors . length === 0 ;
2025-12-21 20:40:32 +01:00
} ;
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 {
2025-12-26 14:03:18 +01:00
setShowPaymentSummary ( true ) ;
window . scrollTo ( { top : document.getElementById ( 'order-form-container' ) ? . offsetTop || 0 , behavior : 'smooth' } ) ;
2025-12-21 20:40:32 +01:00
}
}
} ;
const prevStep = ( ) = > {
2025-12-26 14:03:18 +01:00
if ( showPaymentSummary ) {
setShowPaymentSummary ( false ) ;
return ;
}
2025-12-21 20:40:32 +01:00
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 ) ;
2025-12-26 14:03:18 +01:00
const amountStr = isCustomPrice ? 'Egyedi árazás' : ` ${ totalAmount . toLocaleString ( 'hu-HU' ) } Ft ` ;
2025-12-21 20:40:32 +01:00
if ( isSupabaseConfigured && user ) {
try {
2025-12-26 14:03:18 +01:00
// 1. Create order
const { data : orderData , error } = await supabase . from ( 'orders' ) . insert ( {
2025-12-21 20:40:32 +01:00
user_id : user.id ,
customer_name : formData.name ,
customer_email : formData.email ,
package : formData . package ,
status : 'new' ,
2025-12-26 14:03:18 +01:00
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 ) ;
2025-12-21 20:40:32 +01:00
}
} catch ( err : any ) {
2025-12-26 14:03:18 +01:00
setSubmitError ( 'Hiba a rendelés mentésekor: ' + err . message ) ;
2025-12-21 20:40:32 +01:00
} finally {
setIsSubmitting ( false ) ;
}
} else {
2025-12-26 14:03:18 +01:00
// Demo mode fallback
await new Promise ( r = > setTimeout ( r , 1000 ) ) ;
2025-12-21 20:40:32 +01:00
setIsSubmitted ( true ) ;
setIsSubmitting ( false ) ;
}
} ;
2025-12-26 14:03:18 +01:00
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" ;
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
const formatPrice = ( num : number ) = > num . toLocaleString ( 'hu-HU' ) + ' Ft' ;
if ( loading ) {
return < div className = "p-12 text-center text-gray-500 font-bold animate-pulse" > Betöltés . . . < / div > ;
}
// Ha nincs bejelentkezve, mutassuk a bejelentkezési felhívást
if ( ! user ) {
2025-12-21 20:40:32 +01:00
return (
2025-12-26 14:03:18 +01:00
< div id = "order-form-container" className = "bg-white rounded-[40px] shadow-2xl p-12 text-center border border-gray-100 max-w-4xl mx-auto scroll-mt-24" >
< div className = "w-24 h-24 bg-purple-50 rounded-full flex items-center justify-center mx-auto mb-8 shadow-inner" >
< User className = "w-12 h-12 text-primary" / >
< / div >
< h2 className = "text-3xl font-black text-gray-900 mb-4 tracking-tighter" > Jelentkezz be a folytatáshoz ! < / h2 >
< p className = "text-lg text-gray-600 mb-10 max-w-2xl mx-auto leading-relaxed" >
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 .
< / p >
< div className = "flex flex-col sm:flex-row gap-4 justify-center" >
< Link to = "/auth/login" >
< Button size = "lg" className = "px-12 font-black uppercase tracking-widest text-xs w-full sm:w-auto" > Bejelentkezés < / Button >
< / Link >
< Link to = "/auth/register" >
< Button variant = "outline" size = "lg" className = "px-12 font-black uppercase tracking-widest text-xs w-full sm:w-auto" > Regisztráció < / Button >
< / Link >
< / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
) ;
}
if ( isSubmitted ) {
return (
< div id = "order-form-container" className = "bg-white rounded-[32px] shadow-xl p-12 text-center border border-gray-100 animate-fade-in-up scroll-mt-24 max-w-4xl mx-auto" >
< div className = "w-24 h-24 bg-green-50 rounded-full flex items-center justify-center mx-auto mb-8 shadow-inner" > < CheckCircle className = "w-12 h-12 text-green-500" / > < / div >
< h2 className = "text-3xl font-black text-gray-900 mb-4 tracking-tighter" > Rendelésedet fogadtuk ! < / h2 >
< p className = "text-lg text-gray-600 mb-10 max-w-2xl mx-auto leading-relaxed" > 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 . < / p >
< Link to = "/dashboard" >
< Button size = "lg" className = "px-12 font-black uppercase tracking-widest text-xs" > Vezérlőpult megnyitása < / Button >
< / Link >
2025-12-21 20:40:32 +01:00
< / div >
) ;
}
return (
2025-12-26 14:03:18 +01:00
< div id = "order-form-container" className = "bg-white rounded-[40px] shadow-2xl overflow-hidden border border-gray-100 scroll-mt-24 transition-all duration-500 flex flex-col relative min-h-[600px]" >
{ /* Header with Progress */ }
< div className = "bg-gray-50/80 backdrop-blur-md pt-12 pb-8 px-6 md:px-12 border-b border-gray-100" >
2025-12-21 20:40:32 +01:00
< div className = "text-center mb-10" >
2025-12-26 14:03:18 +01:00
< h2 className = "text-3xl md:text-4xl font-black text-gray-900 mb-3 tracking-tighter uppercase italic" > Projekt Indítása < / h2 >
< p className = "text-gray-500 font-bold uppercase text-[10px] tracking-[0.3em]" >
{ showPaymentSummary
? ( isCustomPrice ? 'Utolsó lépés: Véglegesítés' : 'Utolsó lépés: Fizetés' )
: ` Lépés ${ currentStep } / ${ totalSteps } ` }
< / p >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
{ ! showPaymentSummary && (
< div className = "max-w-4xl mx-auto" >
< div className = "h-1.5 w-full bg-gray-200 rounded-full overflow-hidden" >
< div className = "h-full bg-primary transition-all duration-700 ease-out shadow-[0_0_15px_rgba(124,58,237,0.5)]" style = { { width : ` ${ ( currentStep / totalSteps ) * 100 } % ` } } > < / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< div className = "flex justify-between mt-4" >
{ steps . map ( ( s ) = > (
< div key = { s . id } className = { ` flex flex-col items-center gap-2 ${ s . id === currentStep ? 'opacity-100' : 'opacity-30 hidden md:flex' } ` } >
< div className = { ` w-8 h-8 rounded-lg flex items-center justify-center transition-all ${ s . id === currentStep ? 'bg-primary text-white scale-110 shadow-lg shadow-primary/20' : 'bg-white text-gray-400 border border-gray-200' } ` } >
< s.icon className = "w-4 h-4" / >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
{ s . id === currentStep && < span className = "text-[10px] font-black uppercase tracking-widest text-primary" > { s . title } < / span > }
< / div >
) ) }
2025-12-21 20:40:32 +01:00
< / div >
< / div >
) }
2025-12-26 14:03:18 +01:00
< / div >
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ /* Main Content */ }
< div className = "p-6 md:p-12 flex-grow bg-white" >
{ errors . length > 0 && (
< div className = "bg-red-50 border-2 border-red-100 text-red-600 px-6 py-4 rounded-2xl flex items-start gap-4 mb-8 animate-fade-in shadow-sm" >
< AlertCircle className = "w-6 h-6 flex-shrink-0" / >
< div className = "text-xs font-black uppercase tracking-widest leading-relaxed" >
{ errors . map ( ( err , idx ) = > < p key = { idx } > { err } < / p > ) }
2025-12-21 20:40:32 +01:00
< / div >
< / div >
) }
2025-12-26 14:03:18 +01:00
{ ! showPaymentSummary ? (
< div className = "max-w-3xl mx-auto animate-fade-in" >
{ currentStep === 1 && (
< div className = "space-y-8" >
< div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
< div > < label className = { labelClass } > Teljes Név * < / label > < input type = "text" name = "name" value = { formData . name } onChange = { handleInputChange } placeholder = "Pl: Kovács János" className = { inputClass } / > < / div >
< div > < label className = { labelClass } > Cégnév ( opcionális ) < / label > < input type = "text" name = "company" value = { formData . company } onChange = { handleInputChange } placeholder = "Pl: Kreatív Kft." className = { inputClass } / > < / div >
< div > < label className = { labelClass } > E - mail * < / label > < input type = "email" value = { formData . email } readOnly className = { ` ${ inputClass } bg-white text-gray-400 ` } / > < / div >
< div > < label className = { labelClass } > Telefonszám * < / label > < input type = "tel" name = "phone" value = { formData . phone } onChange = { handleInputChange } placeholder = "+36..." className = { inputClass } / > < / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< div className = "pt-6" >
< label className = { labelClass } > Választott Csomag < / label >
< div className = "grid grid-cols-1 sm:grid-cols-3 gap-4" >
{ availablePackages . map ( ( pkg ) = > (
< button key = { pkg . id } onClick = { ( ) = > setFormData ( { . . . formData , package : pkg . name } ) } className = { ` p-4 rounded-2xl border-2 text-left transition-all ${ formData . package === pkg . name ? 'border-primary bg-purple-50 shadow-md' : 'border-gray-100 hover:border-gray-200 bg-white' } ` } >
< p className = { ` text-xs font-black uppercase tracking-widest ${ formData . package === pkg . name ? 'text-primary' : 'text-gray-400' } ` } > { pkg . name } < / p >
< p className = "text-sm font-bold text-gray-900 mt-1" > { pkg . price } < / p >
< / button >
) ) }
< / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 2 && (
< div className = "space-y-6" >
< label className = { labelClass } > Mutassa be röviden vállalkozását ! < / label >
< textarea name = "description" rows = { 8 } value = { formData . description } onChange = { handleInputChange } placeholder = "Mivel foglalkozik a cég, mi a fő profilja?" className = { inputClass } > < / textarea >
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 3 && (
< div className = "space-y-6" >
< label className = { labelClass } > Melyek a weboldal fő céljai ? < / label >
< div className = "grid grid-cols-1 sm:grid-cols-2 gap-4" >
{ [ 'Cég bemutatása' , 'Online értékesítés' , 'Időpontfoglalás' , 'Ügyfélszerzés' , 'Információközlés' ] . map ( goal = > (
< button key = { goal } onClick = { ( ) = > handleCheckboxChange ( 'goals' , goal ) } className = { ` p-4 rounded-2xl border-2 text-left font-bold transition-all ${ formData . goals . includes ( goal ) ? 'border-primary bg-purple-50 text-primary' : 'border-gray-100 text-gray-500 bg-white' } ` } > { goal } < / button >
) ) }
< / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 4 && (
< div className = "space-y-8" >
< label className = { labelClass } > Milyen aloldalakat szeretne ? < / label >
< div className = "grid grid-cols-1 sm:grid-cols-2 gap-4" >
{ [ 'Rólunk' , 'Szolgáltatások' , 'Referenciák' , 'Gyakori Kérdések' , 'Blog' , 'Kapcsolat' ] . map ( item = > (
< button key = { item } onClick = { ( ) = > handleCheckboxChange ( 'content' , item ) } className = { ` p-4 rounded-2xl border-2 text-left font-bold transition-all ${ formData . content . includes ( item ) ? 'border-primary bg-purple-50 text-primary' : 'border-gray-100 text-gray-500 bg-white' } ` } > { item } < / button >
) ) }
< / div >
< div className = "pt-6 border-t border-gray-100" >
< label className = { labelClass } > Vannak meglévő anyagai ? ( Link ) < / label >
< input type = "text" name = "contentLink" value = { formData . contentLink } onChange = { handleInputChange } placeholder = "Google Drive, Dropbox link..." className = { inputClass } / >
< / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 5 && (
< div className = "space-y-8" >
< label className = { labelClass } > Design preferenciák ( Fő színek ) < / label >
< div className = "grid grid-cols-1 sm:grid-cols-3 gap-6" >
< div > < p className = "text-[10px] font-black text-gray-400 mb-2" > FŐSZÍN < / p > < input type = "color" value = { formData . primaryColor || '#7c3aed' } onChange = { e = > setFormData ( { . . . formData , primaryColor : e.target.value } ) } className = "w-full h-12 rounded-xl cursor-pointer bg-white" / > < / div >
< div > < p className = "text-[10px] font-black text-gray-400 mb-2" > MELLÉKSZÍN < / p > < input type = "color" value = { formData . secondaryColor || '#3b82f6' } onChange = { e = > setFormData ( { . . . formData , secondaryColor : e.target.value } ) } className = "w-full h-12 rounded-xl cursor-pointer bg-white" / > < / div >
< div > < p className = "text-[10px] font-black text-gray-400 mb-2" > HÁTTÉRSZÍN < / p > < input type = "color" value = { formData . balanceColor || '#ffffff' } onChange = { e = > setFormData ( { . . . formData , balanceColor : e.target.value } ) } className = "w-full h-12 rounded-xl cursor-pointer bg-white" / > < / div >
< / div >
< div className = "pt-6" >
< label className = { labelClass } > Stílusirányzat ( Max 2 ) < / label >
< div className = "flex flex-wrap gap-3" >
{ styleOptions . map ( style = > (
< button key = { style } onClick = { ( ) = > handleCheckboxChange ( 'style' , style ) } className = { ` px-5 py-2.5 rounded-full border-2 text-[10px] font-black uppercase tracking-widest transition-all ${ formData . style . includes ( style ) ? 'border-primary bg-primary text-white' : 'border-gray-100 text-gray-400 bg-white' } ` } > { style } < / button >
) ) }
< / div >
2025-12-21 20:40:32 +01:00
< / div >
< / div >
2025-12-26 14:03:18 +01:00
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 6 && (
< div className = "space-y-6" >
< label className = { labelClass } > Milyen funkciókra van szüksége ? < / label >
< div className = "grid grid-cols-1 sm:grid-cols-2 gap-4" >
{ [ 'Kapcsolatfelvételi űrlap' , 'Hírlevél feliratkozás' , 'Kereső funkció' , 'Többnyelvűség' , 'Admin felület' , 'Bankkártyás fizetés' ] . map ( feat = > (
< button key = { feat } onClick = { ( ) = > handleCheckboxChange ( 'features' , feat ) } className = { ` p-4 rounded-2xl border-2 text-left font-bold transition-all ${ formData . features . includes ( feat ) ? 'border-primary bg-purple-50 text-primary' : 'border-gray-100 text-gray-500 bg-white' } ` } > { feat } < / button >
) ) }
< / div >
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 7 && (
< div className = "space-y-8 animate-fade-in" >
< label className = { labelClass } > Inspirációs weboldalak é s megjegyzések < / label >
< div className = "space-y-6" >
{ [ 0 , 1 , 2 ] . map ( i = > (
< div key = { i } className = "grid grid-cols-1 md:grid-cols-2 gap-4 p-4 bg-gray-50/50 rounded-2xl border border-gray-100" >
< div className = "space-y-2" >
< p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest ml-1" > Példa oldal { i + 1 } linkje < / p >
< input
type = "url"
value = { formData . inspirations [ i ] . url }
onChange = { e = > {
const ins = [ . . . formData . inspirations ] ;
ins [ i ] . url = e . target . value ;
setFormData ( { . . . formData , inspirations : ins } ) ;
} }
placeholder = "https://..."
className = { inputClass }
/ >
< / div >
< div className = "space-y-2" >
< p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest ml-1" > Mi tetszik rajta ? < / p >
< input
type = "text"
value = { formData . inspirations [ i ] . comment }
onChange = { e = > {
const ins = [ . . . formData . inspirations ] ;
ins [ i ] . comment = e . target . value ;
setFormData ( { . . . formData , inspirations : ins } ) ;
} }
placeholder = "Színek, elrendezés, stílus..."
className = { inputClass }
/ >
< / div >
< / div >
) ) }
< / div >
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 8 && (
< div className = "space-y-6" >
< label className = { labelClass } > Egyéb megjegyzések az extrákhoz < / label >
< textarea name = "notes" rows = { 8 } value = { formData . notes } onChange = { handleInputChange } placeholder = "Bármilyen egyéb kérés, funkció..." className = { inputClass } > < / textarea >
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 9 && (
< div className = "space-y-8" >
< div className = "flex gap-4 p-2 bg-gray-100 rounded-2xl w-fit mx-auto mb-8" >
< button onClick = { ( ) = > setFormData ( { . . . formData , billingType : 'individual' } ) } className = { ` px-6 py-2 rounded-xl text-xs font-black uppercase tracking-widest transition-all ${ formData . billingType === 'individual' ? 'bg-white text-primary shadow-sm' : 'text-gray-400' } ` } > Magánszemély < / button >
< button onClick = { ( ) = > setFormData ( { . . . formData , billingType : 'company' } ) } className = { ` px-6 py-2 rounded-xl text-xs font-black uppercase tracking-widest transition-all ${ formData . billingType === 'company' ? 'bg-white text-primary shadow-sm' : 'text-gray-400' } ` } > Cég < / button >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
< div className = "md:col-span-2" > < label className = { labelClass } > { formData . billingType === 'company' ? 'Cégnév *' : 'Számlázási Név *' } < / label > < input type = "text" name = "billingName" value = { formData . billingName } onChange = { handleInputChange } className = { inputClass } / > < / div >
{ formData . billingType === 'company' && < div className = "md:col-span-2" > < label className = { labelClass } > Adószám * < / label > < input type = "text" name = "taxNumber" value = { formData . taxNumber } onChange = { handleInputChange } placeholder = "XXXXXXXX-Y-ZZ" className = { inputClass } / > < / div > }
< div > < label className = { labelClass } > Irányítószám * < / label > < input type = "text" name = "billingZip" value = { formData . billingZip } onChange = { handleInputChange } className = { inputClass } / > < / div >
< div > < label className = { labelClass } > Város * < / label > < input type = "text" name = "billingCity" value = { formData . billingCity } onChange = { handleInputChange } className = { inputClass } / > < / div >
< div className = "md:col-span-2" > < label className = { labelClass } > Cím * < / label > < input type = "text" name = "billingAddress" value = { formData . billingAddress } onChange = { handleInputChange } placeholder = "Utca, házszám..." className = { inputClass } / > < / div >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< / div >
) }
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
{ currentStep === 10 && (
< div className = "space-y-10" >
< div className = "bg-gray-50 p-8 rounded-[32px] border border-gray-200" >
< div className = "grid grid-cols-1 md:grid-cols-2 gap-8" >
< div > < p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1" > Csomag < / p > < p className = "text-xl font-black text-primary" > { formData . package } < / p > < / div >
< div > < p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1" > Ü gyfél < / p > < p className = "text-lg font-bold text-gray-900" > { formData . name } < / p > < / div >
< div className = "md:col-span-2 pt-6 border-t border-gray-200" > < p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1" > Számlázási Cím < / p > < p className = "font-bold text-gray-700" > { formData . billingZip } { formData . billingCity } , { formData . billingAddress } < / p > < / div >
< / div >
< / div >
< div className = "space-y-4" >
< label className = "flex items-start gap-4 cursor-pointer group p-4 rounded-2xl border border-transparent hover:bg-purple-50/50 transition-colors" >
< input type = "checkbox" checked = { privacyAccepted } onChange = { e = > setPrivacyAccepted ( e . target . checked ) } className = "w-5 h-5 rounded text-primary mt-0.5" / >
< span className = "text-sm font-bold text-gray-600 group-hover:text-gray-900 transition-colors" > Elfogadom az < Link to = "/privacy" className = "text-primary underline" > adatkezelési tájékoztatót < / Link > . < / span >
< / label >
< label className = "flex items-start gap-4 cursor-pointer group p-4 rounded-2xl border border-transparent hover:bg-purple-50/50 transition-colors" >
< input type = "checkbox" checked = { aszfAccepted } onChange = { e = > setAszfAccepted ( e . target . checked ) } className = "w-5 h-5 rounded text-primary mt-0.5" / >
< span className = "text-sm font-bold text-gray-600 group-hover:text-gray-900 transition-colors" > Elfogadom az < Link to = "/terms" className = "text-primary underline" > á ltalános szerződési feltételeket < / Link > . < / span >
< / label >
2025-12-21 20:40:32 +01:00
< / div >
< / div >
2025-12-26 14:03:18 +01:00
) }
< / div >
) : (
/* PAYMENT SUMMARY / CUSTOM ORDER VIEW */
< div className = "max-w-2xl mx-auto space-y-10 animate-fade-in-up" >
{ isCustomPrice ? (
/* CUSTOM PRICE VIEW */
< >
< div className = "text-center" >
< div className = "w-20 h-20 bg-blue-50 rounded-3xl flex items-center justify-center mx-auto mb-6 text-blue-600 shadow-sm" >
< FileText className = "w-10 h-10" / >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< h3 className = "text-3xl font-black text-gray-900 tracking-tight mb-4" > Rendelés Véglegesítése < / h3 >
< p className = "text-gray-600 font-medium leading-relaxed" >
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 .
< / p >
< / div >
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
< div className = "bg-primary/5 p-10 rounded-[32px] border-2 border-primary/20 text-center shadow-xl shadow-primary/5 relative overflow-hidden" >
< div className = "absolute -top-10 -right-10 w-40 h-40 bg-primary/10 rounded-full blur-3xl" > < / div >
< p className = "text-[11px] font-black text-primary uppercase tracking-[0.3em] mb-4" > Választott Konstrukció < / p >
< div className = "text-4xl md:text-5xl font-black text-primary mb-6 tracking-tighter" >
Egyedi Á razás
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< p className = "text-xs text-primary/60 font-bold uppercase tracking-widest leading-relaxed" >
A "Rendelés Leadása" gombra kattintva rögzítjük igényedet .
< / p >
< / div >
< / >
) : (
/* STANDARD PAYMENT VIEW */
< >
< div className = "text-center" >
< div className = "w-20 h-20 bg-green-50 rounded-3xl flex items-center justify-center mx-auto mb-6 text-green-600 shadow-sm" >
< Wallet className = "w-10 h-10" / >
2025-12-21 20:40:32 +01:00
< / div >
2025-12-26 14:03:18 +01:00
< h3 className = "text-3xl font-black text-gray-900 tracking-tight mb-4" > Rendelés Ö sszesítése < / h3 >
< p className = "text-gray-600 font-medium leading-relaxed" >
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 .
< / p >
< / div >
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
< div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
< div className = "bg-gray-50 p-6 rounded-[24px] border border-gray-100 flex flex-col items-center text-center" >
< p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2" > Projekt Teljes Á ra < / p >
< p className = "text-xl font-bold text-gray-900" > { formatPrice ( totalAmount ) } < / p >
< / div >
< div className = "bg-gray-50 p-6 rounded-[24px] border border-gray-100 flex flex-col items-center text-center" >
< p className = "text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2" > Fennmaradó ( Demó után ) < / p >
< p className = "text-xl font-bold text-gray-900" > { formatPrice ( remainingAmount ) } < / p >
< / div >
< / div >
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
< div className = "bg-primary/5 p-10 rounded-[32px] border-2 border-primary/20 text-center shadow-xl shadow-primary/5 relative overflow-hidden" >
< div className = "absolute -top-10 -right-10 w-40 h-40 bg-primary/10 rounded-full blur-3xl" > < / div >
< p className = "text-[11px] font-black text-primary uppercase tracking-[0.3em] mb-4" > Jelenleg Fizetendő Előleg < / p >
< div className = "text-5xl md:text-6xl font-black text-primary mb-6 tracking-tighter" >
{ formatPrice ( advanceAmount ) }
< / div >
< p className = "text-xs text-primary/60 font-bold uppercase tracking-widest leading-relaxed" >
A gombra kattintva á tirányítjuk a biztonságos Stripe fizetési oldalra .
< / p >
< / div >
2025-12-21 20:40:32 +01:00
2025-12-26 14:03:18 +01:00
< div className = "bg-amber-50 border border-amber-200 p-6 rounded-2xl flex gap-4" >
< div className = "shrink-0" > < Info className = "w-5 h-5 text-amber-500" / > < / div >
< p className = "text-xs text-amber-800 font-medium leading-relaxed" >
< strong > Fontos : < / strong > 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é .
< / p >
< / div >
< / >
) }
2025-12-21 20:40:32 +01:00
< / div >
) }
< / div >
{ /* Footer Navigation */ }
2025-12-26 14:03:18 +01:00
< div className = "bg-white border-t border-gray-100 p-8 flex justify-between items-center rounded-b-[40px]" >
< Button onClick = { prevStep } variant = "white" disabled = { currentStep === 1 || isSubmitting } className = { ` ${ currentStep === 1 ? 'opacity-0' : '' } border border-gray-200 font-black uppercase text-[10px] tracking-widest px-10 ` } > Vissza < / Button >
{ ! showPaymentSummary ? (
< Button onClick = { nextStep } className = "font-black uppercase text-[10px] tracking-widest px-12 shadow-lg shadow-primary/20" >
{ currentStep < totalSteps ? 'Következő' : 'Rendelés Leadása' } < ArrowRight className = "w-4 h-4 ml-2" / >
2025-12-21 20:40:32 +01:00
< / Button >
) : (
2025-12-26 14:03:18 +01:00
< Button
onClick = { handleSubmit }
disabled = { isSubmitting }
className = "font-black uppercase text-[10px] tracking-widest px-16 py-6 shadow-2xl shadow-primary/40 h-auto"
>
{ isSubmitting ? (
< > < RefreshCw className = "w-4 h-4 animate-spin mr-2" / > FELDOLGOZÁS . . . < / >
) : isCustomPrice ? (
< > < Send className = "w-4 h-4 mr-2" / > RENDELÉS LEADÁSA < / >
) : (
< > < CreditCard className = "w-4 h-4 mr-2" / > FIZETÉS INDÍTÁSA < / >
2025-12-21 20:40:32 +01:00
) }
< / Button >
) }
< / div >
< / div >
) ;
2025-12-26 14:03:18 +01:00
} ;