Files
MotionWebStudio/components/OrderForm.tsx
2025-12-21 20:40:32 +01:00

876 lines
45 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState } from 'react';
import {
Send, CheckCircle, AlertCircle, Globe, Server, Check,
ArrowRight, ArrowLeft, User, FileText, Target, Layout,
Palette, Zap, Lightbulb, Settings, ClipboardCheck, Lock,
Cloud, Upload
} from 'lucide-react';
import { Button } from './Button';
import { useAuth } from '../context/AuthContext';
import { Link } from 'react-router-dom';
import { supabase, isSupabaseConfigured } from '../lib/supabaseClient';
interface Inspiration {
url: string;
comment: string;
}
export const OrderForm: React.FC = () => {
const { user, loading } = useAuth();
const [currentStep, setCurrentStep] = useState(1);
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);
const totalSteps = 9;
const [formData, setFormData] = useState({
// 1. Kapcsolattartás
name: '',
company: '',
email: user?.email || '',
phone: '',
package: 'Pro Web', // Default selection updated
// 2. Bemutatkozás
description: '',
// 3. Célok
goals: [] as string[],
goalOther: '',
successCriteria: '',
// 4. Tartalom
content: [] as string[],
contentOther: '',
existingAssets: 'Nincs' as 'Igen' | 'Nem' | 'Részben',
contentLink: '', // New field for drive link
// 5. Design
primaryColor: '',
secondaryColor: '',
balanceColor: '',
style: [] as string[],
targetAudience: '',
// 6. Funkciók
features: [] as string[],
// 7. Inspirációk
inspirations: [
{ url: '', comment: '' },
{ url: '', comment: '' },
{ url: '', comment: '' }
] as Inspiration[],
// 8. Extrák & Megjegyzések
extras: [] as string[],
domainName: '',
notes: ''
});
// Helper arrays
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: 'Összegzés', icon: ClipboardCheck },
];
// Auto-fill user data (Name and Email) when user loads
React.useEffect(() => {
const prefillUserData = async () => {
if (!user) return;
let emailToSet = user.email || '';
let nameToSet = '';
// 1. Try metadata (from session - fastest)
const meta = user.user_metadata;
if (meta?.last_name && meta?.first_name) {
// Hungarian order: Lastname Firstname
nameToSet = `${meta.last_name} ${meta.first_name}`;
}
// 2. Fallback to DB if Supabase is configured and metadata is missing name
if (!nameToSet && isSupabaseConfigured) {
try {
const { data } = await supabase
.from('profiles')
.select('first_name, last_name')
.eq('id', user.id)
.maybeSingle();
if (data?.first_name && data?.last_name) {
nameToSet = `${data.last_name} ${data.first_name}`;
}
} catch (error) {
console.error('Error fetching user profile for order form:', error);
}
}
setFormData(prev => {
// Only update if fields are empty to avoid overwriting user input
if (prev.name && prev.email) return prev;
return {
...prev,
email: prev.email || emailToSet,
name: prev.name || nameToSet
};
});
};
prefillUserData();
}, [user]);
// If loading auth state, show a skeleton or loader
if (loading) {
return (
<div id="order-form-container" className="bg-white rounded-3xl shadow-xl p-12 text-center border border-gray-100 min-h-[400px] flex items-center justify-center">
<div className="animate-pulse text-gray-400">Betöltés...</div>
</div>
);
}
// Auth Protection - Lock Screen
if (!user) {
return (
<div id="order-form-container" className="bg-white rounded-3xl shadow-xl overflow-hidden border border-gray-100 scroll-mt-24 max-w-4xl mx-auto">
<div className="bg-gradient-to-br from-[#eef2ff] to-[#f5f3ff] pt-12 pb-8 px-6 md:px-12 border-b border-white shadow-sm text-center">
<div className="w-20 h-20 bg-white rounded-full flex items-center justify-center mx-auto mb-6 shadow-md text-[#4e6bff]">
<Lock className="w-10 h-10" />
</div>
<h2 className="text-3xl font-extrabold text-[#111827] mb-3">Jelentkezzen be a rendeléshez</h2>
<p className="text-[#4b5563] text-lg max-w-xl mx-auto">
Weboldal rendelés leadásához kérjük, jelentkezzen be fiókjába, vagy regisztráljon egyet ingyenesen.
</p>
</div>
<div className="p-12 text-center bg-white">
<div className="flex flex-col sm:flex-row gap-4 justify-center max-w-md mx-auto">
<Link to="/auth/login" className="w-full">
<Button fullWidth size="lg">Bejelentkezés</Button>
</Link>
<Link to="/auth/register" className="w-full">
<Button variant="outline" fullWidth size="lg">Regisztráció</Button>
</Link>
</div>
<p className="mt-8 text-sm text-gray-500">
A regisztráció mindössze 1 percet vesz igénybe, és segít a projekt későbbi nyomon követésében.
</p>
</div>
</div>
);
}
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 {
return { ...prev, [category]: [...list, value] };
}
});
};
const handleInspirationChange = (index: number, field: 'url' | 'comment', value: string) => {
const newInspirations = [...formData.inspirations];
newInspirations[index] = { ...newInspirations[index], [field]: value };
setFormData(prev => ({ ...prev, inspirations: newInspirations }));
};
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.email) newErrors.push('Az e-mail cím megadása kötelező.');
if (!formData.phone) newErrors.push('A telefonszám megadása kötelező.');
}
if (newErrors.length > 0) {
setErrors(newErrors);
return false;
}
setErrors([]);
return true;
};
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 {
handleSubmit();
}
}
};
const prevStep = () => {
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);
if (!privacyAccepted) {
setSubmitError('A rendelés leadásához el kell fogadnia az Adatkezelési tájékoztatót.');
setIsSubmitting(false);
return;
}
if (!aszfAccepted) {
setSubmitError('A rendelés leadásához el kell fogadnia az Általános Szerződési Feltételeket (ÁSZF).');
setIsSubmitting(false);
return;
}
// Determine amount text
const amount =
formData.package === 'Landing Page' ? '190.000 Ft' :
formData.package === 'Pro Web' ? '350.000 Ft' :
'Egyedi Árazás';
if (isSupabaseConfigured && user) {
try {
const { error } = await supabase.from('orders').insert({
user_id: user.id,
customer_name: formData.name,
customer_email: formData.email,
package: formData.package,
status: 'new',
amount: amount,
details: formData
});
if (error) {
throw error;
}
setIsSubmitted(true);
window.scrollTo({ top: document.getElementById('order-form-container')?.offsetTop || 0, behavior: 'smooth' });
} catch (err: any) {
console.error('Error submitting order:', err);
setSubmitError('Hiba történt a rendelés elküldésekor: ' + err.message);
} finally {
setIsSubmitting(false);
}
} else {
// Fallback for Demo Mode
console.log('Demo Mode: Order Data:', formData);
await new Promise(resolve => setTimeout(resolve, 1500)); // Simulate delay
setIsSubmitted(true);
setIsSubmitting(false);
window.scrollTo({ top: document.getElementById('order-form-container')?.offsetTop || 0, behavior: 'smooth' });
}
};
// Modern Input Style Class - MotionWeb Style
const inputClass = "w-full px-4 py-3 rounded-lg border border-gray-200 bg-white text-[#111111] placeholder-gray-400 focus:ring-4 focus:ring-[#4e6bff]/10 focus:border-[#4e6bff] outline-none transition-all shadow-sm";
const labelClass = "text-sm font-semibold text-gray-800 block mb-2";
const checkboxClass = "w-5 h-5 text-[#4e6bff] rounded focus:ring-[#4e6bff] border-gray-300 flex-shrink-0 transition-colors cursor-pointer";
const ColorPickerSection = ({ label, selected, onChange }: { label: string, selected: string, onChange: (color: string) => void }) => (
<div className="space-y-2">
<label className={labelClass}>{label}</label>
<div className="flex flex-wrap gap-3">
{colorOptions.map((color) => (
<button
key={color.name}
type="button"
onClick={() => onChange(color.name)}
className={`w-9 h-9 rounded-full border flex items-center justify-center transition-all hover:scale-110 hover:shadow-md ${selected === color.name ? 'border-gray-800 ring-2 ring-offset-2 ring-gray-200 scale-110' : 'border-gray-200'}`}
style={{ backgroundColor: color.value }}
title={color.name}
>
{selected === color.name && <Check className={`w-4 h-4 ${['Fehér', 'Sárga'].includes(color.name) ? 'text-black' : 'text-white'}`} />}
</button>
))}
</div>
<p className="text-xs text-gray-500 min-h-[1.25rem]">{selected ? `Választott: ${selected}` : ''}</p>
</div>
);
if (isSubmitted) {
return (
<div id="order-form-container" className="bg-white rounded-3xl 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-6 shadow-sm">
<CheckCircle className="w-12 h-12 text-green-500" />
</div>
<h2 className="text-3xl font-extrabold text-gray-900 mb-4">Rendelését sikeresen rögzítettük!</h2>
<p className="text-xl text-gray-600 mb-8 max-w-2xl mx-auto leading-relaxed">
Átirányítjuk az előlegfizetési oldalra. Amennyiben ez nem történik meg, kollégáink hamarosan felveszik Önnel a kapcsolatot.
</p>
<Button onClick={() => { setIsSubmitted(false); setCurrentStep(1); }} variant="outline">Új űrlap kitöltése</Button>
</div>
);
}
return (
<div id="order-form-container" className="bg-white rounded-3xl shadow-xl overflow-hidden border border-gray-100 scroll-mt-24 transition-all duration-500 flex flex-col relative">
{/* Light Gradient Header & Step Navigation */}
<div className="bg-gradient-to-br from-[#eef2ff] to-[#f5f3ff] pt-12 pb-8 px-6 md:px-12 border-b border-white shadow-sm">
<div className="text-center mb-10">
<h2 className="text-3xl md:text-4xl font-extrabold text-[#111827] mb-3">Rendelés Leadása</h2>
<p className="text--[#4b5563] text-lg max-w-2xl mx-auto">Töltse ki az űrlapot a pontos ajánlatadáshoz, és segítünk megvalósítani elképzeléseit.</p>
</div>
{/* Desktop Stepper Navigation */}
<div className="hidden lg:flex justify-between items-center relative max-w-6xl mx-auto px-4 mb-4">
{/* Background Line */}
<div className="absolute left-4 right-4 top-5 transform -translate-y-1/2 h-1 bg-gray-200 rounded-full -z-10" />
{/* Active Progress Line */}
<div
className="absolute left-4 top-5 transform -translate-y-1/2 h-1 bg-[#4e6bff] rounded-full -z-10 transition-all duration-500 ease-out"
style={{ width: `${((currentStep - 1) / (totalSteps - 1)) * 96}%` }} // 96% to account for padding
/>
{steps.map((step) => {
const isActive = step.id === currentStep;
const isCompleted = step.id < currentStep;
return (
<div key={step.id} className="relative flex flex-col items-center group">
<div className={`w-10 h-10 rounded-full flex items-center justify-center transition-all duration-300 border-2 z-10 ${
isActive
? 'bg-[#4e6bff] border-[#4e6bff] text-white shadow-[0_0_0_4px_rgba(78,107,255,0.2)] scale-110'
: isCompleted
? 'bg-[#4e6bff] border-[#4e6bff] text-white'
: 'bg-white border-gray-300 text-gray-400'
}`}>
{isCompleted ? <Check className="w-5 h-5" /> : <step.icon className="w-5 h-5" />}
</div>
<div className={`absolute top-12 text-xs font-semibold whitespace-nowrap transition-all duration-300 ${
isActive ? 'text-[#4e6bff] translate-y-0 opacity-100' : 'text-[#6b7280] translate-y-1'
}`}>
{step.title}
</div>
</div>
);
})}
</div>
{/* Mobile/Tablet Progress Bar */}
<div className="lg:hidden max-w-2xl mx-auto">
<div className="flex justify-between text-xs font-bold text-gray-500 mb-2 uppercase tracking-wider">
<span>Lépés {currentStep} / {totalSteps}</span>
<span className="text-[#4e6bff]">{steps[currentStep - 1].title}</span>
</div>
<div className="h-2 w-full bg-gray-200 rounded-full overflow-hidden">
<div
className="h-full bg-[#4e6bff] shadow-[0_0_10px_rgba(78,107,255,0.5)] transition-all duration-500 ease-out"
style={{ width: `${(currentStep / totalSteps) * 100}%` }}
></div>
</div>
</div>
</div>
<div className="p-6 md:p-12 min-h-[400px] bg-white">
{errors.length > 0 && (
<div className="bg-red-50 border border-red-100 text-red-600 px-4 py-3 rounded-xl flex items-start gap-3 mb-8 animate-fade-in shadow-sm">
<AlertCircle className="w-5 h-5 mt-0.5 flex-shrink-0" />
<div>
<p className="font-bold">Kérjük, javítsa a következő hibákat:</p>
<ul className="list-disc list-inside text-sm mt-1 opacity-80">
{errors.map((err, idx) => <li key={idx}>{err}</li>)}
</ul>
</div>
</div>
)}
{submitError && (
<div className="bg-red-50 border border-red-100 text-red-600 px-4 py-3 rounded-xl flex items-start gap-3 mb-8 animate-fade-in shadow-sm">
<AlertCircle className="w-5 h-5 mt-0.5 flex-shrink-0" />
<div>{submitError}</div>
</div>
)}
{/* Step 1: Kapcsolattartási adatok */}
{currentStep === 1 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<User className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Kapcsolattartási adatok</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label className={labelClass}>Név <span className="text-red-500">*</span></label>
<input type="text" name="name" value={formData.name} onChange={handleInputChange} placeholder="Add meg a neved" className={inputClass} />
</div>
<div>
<label className={labelClass}>Cég neve <span className="text-gray-400 font-normal">(opcionális)</span></label>
<input type="text" name="company" value={formData.company} onChange={handleInputChange} placeholder="Ha van céged, írd ide a nevét" className={inputClass} />
</div>
<div>
<label className={labelClass}>E-mail cím <span className="text-red-500">*</span></label>
<input type="email" name="email" value={formData.email} onChange={handleInputChange} placeholder="valami@valami.hu" className={inputClass} readOnly />
<p className="text-xs text-gray-500 mt-1">A bejelentkezett e-mail címed.</p>
</div>
<div>
<label className={labelClass}>Telefonszám <span className="text-red-500">*</span></label>
<input type="tel" name="phone" value={formData.phone} onChange={handleInputChange} placeholder="+36..." className={inputClass} />
</div>
</div>
<div className="pt-4">
<label className={labelClass}>Választott csomag</label>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
{['Landing Page', 'Pro Web', 'Enterprise'].map((pkg) => (
<label key={pkg} className={`relative flex items-center gap-3 px-4 py-4 rounded-xl border-2 cursor-pointer transition-all ${formData.package === pkg ? 'border-[#4e6bff] bg-blue-50/30' : 'border-gray-100 bg-gray-50 hover:border-gray-200'}`}>
<input type="radio" name="package" value={pkg} checked={formData.package === pkg} onChange={(e) => setFormData({...formData, package: e.target.value})} className="sr-only" />
<div className={`w-5 h-5 rounded-full border-2 flex-shrink-0 flex items-center justify-center ${formData.package === pkg ? 'border-[#4e6bff]' : 'border-gray-300'}`}>
{formData.package === pkg && <div className="w-2.5 h-2.5 rounded-full bg-[#4e6bff]" />}
</div>
<span className={`font-bold text-sm sm:text-base ${formData.package === pkg ? 'text-[#4e6bff]' : 'text-gray-700'}`}>{pkg}</span>
</label>
))}
</div>
</div>
</div>
)}
{currentStep === 2 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<FileText className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">A vállalkozás rövid bemutatása</h3>
</div>
<div>
<label className={labelClass}>Mivel foglalkozik a cég?</label>
<textarea name="description" rows={6} value={formData.description} onChange={handleInputChange} placeholder="Pl.: vízszereléssel és háztartási gépek javításával foglalkozunk." className={inputClass}></textarea>
<p className="text-sm text-gray-500 mt-2 bg-gray-50 p-3 rounded-lg border border-gray-100 inline-block">💡 Tipp: Írjon le mindent, amit fontosnak tart a tevékenységével kapcsolatban.</p>
</div>
</div>
)}
{currentStep === 3 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Target className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Mi a weboldal célja?</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{['Cég bemutatása', 'Termék / szolgáltatás értékesítés', 'Időpontfoglalás vagy ügyfélszerzés', 'Hírlevél / e-mail lista építése', 'Közösségépítés', 'Egyéb'].map((goal) => (
<div key={goal}>
<label className={`flex items-center space-x-3 cursor-pointer p-4 rounded-xl border transition-all h-full shadow-sm ${formData.goals.includes(goal) ? 'border-[#4e6bff] bg-blue-50/20' : 'border-gray-200 bg-white hover:border-gray-300'}`}>
<input type="checkbox" checked={formData.goals.includes(goal)} onChange={() => handleCheckboxChange('goals', goal)} className={checkboxClass} />
<span className="text-gray-900 font-medium">{goal}</span>
</label>
{goal === 'Egyéb' && formData.goals.includes('Egyéb') && (
<div className="mt-2 animate-fade-in">
<input type="text" name="goalOther" value={formData.goalOther} onChange={handleInputChange} placeholder="Kérjük fejtse ki..." className={`${inputClass} text-sm py-2`} />
</div>
)}
</div>
))}
</div>
<div className="space-y-2 pt-4">
<label className={labelClass}>Mi számít sikernek a weboldal esetében? <span className="text-gray-400 font-normal">(opcionális)</span></label>
<input type="text" name="successCriteria" value={formData.successCriteria} onChange={handleInputChange} placeholder="Több megrendelés, több hívás, több látogató..." className={inputClass} />
</div>
</div>
)}
{currentStep === 4 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Layout className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Tartalom és szerkezet</h3>
</div>
<div>
<label className={labelClass}>Milyen aloldalakat tervez?</label>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
{['Rólunk', 'Szolgáltatások', 'Termékek', 'Referenciák / Vélemények', 'Blog / Hírek', 'Kapcsolat', 'Egyéb'].map((item) => (
<div key={item}>
<label className={`flex items-center space-x-3 cursor-pointer p-3 rounded-lg border transition-all ${formData.content.includes(item) ? 'border-[#4e6bff] bg-blue-50/20' : 'border-transparent hover:bg-gray-50'}`}>
<input type="checkbox" checked={formData.content.includes(item)} onChange={() => handleCheckboxChange('content', item)} className={checkboxClass} />
<span className="text-gray-800 font-medium">{item}</span>
</label>
{item === 'Egyéb' && formData.content.includes('Egyéb') && (
<input type="text" name="contentOther" value={formData.contentOther} onChange={handleInputChange} placeholder="Egyéb oldalak..." className={`${inputClass} mt-1 py-2 text-sm`} />
)}
</div>
))}
</div>
</div>
<div className="pt-8 border-t border-gray-100">
<label className={labelClass}>Van már meglévő szöveg, kép vagy logó?</label>
<div className="flex flex-wrap gap-4 mt-3">
{['Igen', 'Nem', 'Részben'].map((opt) => (
<label key={opt} className={`flex items-center gap-3 px-5 py-3 rounded-lg border cursor-pointer transition-all ${formData.existingAssets === opt ? 'border-[#4e6bff] bg-blue-50/20 text-[#4e6bff]' : 'border-gray-200 bg-white hover:bg-gray-50 text-gray-700'}`}>
<input type="radio" name="existingAssets" value={opt} checked={formData.existingAssets === opt} onChange={(e) => setFormData({...formData, existingAssets: e.target.value as any})} className="w-4 h-4 text-[#4e6bff] focus:ring-[#4e6bff]" />
<span className="font-semibold">{opt}</span>
</label>
))}
</div>
{/* Content Upload / Link Section */}
{(formData.existingAssets === 'Igen' || formData.existingAssets === 'Részben') && (
<div className="mt-6 bg-blue-50 border border-blue-100 p-6 rounded-xl animate-fade-in">
<h4 className="font-bold text-blue-900 mb-3 flex items-center gap-2">
<Cloud className="w-5 h-5" /> Tartalom megosztása
</h4>
<p className="text-sm text-blue-800 mb-4">
Kérjük, töltse fel a meglévő tartalmakat (képek, szövegek, logó) egy felhő tárhelyre (pl. Google Drive) és ossza meg a linket, vagy töltsön fel fájlt (max 1GB).
</p>
<div className="space-y-4">
<div>
<label className={labelClass}>Felhő mappa linkje</label>
<input
type="url"
name="contentLink"
value={formData.contentLink}
onChange={handleInputChange}
placeholder="https://drive.google.com/..."
className={inputClass}
/>
</div>
<div>
<label className={labelClass}>Vagy fájl feltöltése</label>
<div className="border-2 border-dashed border-blue-200 rounded-lg p-6 bg-white text-center hover:bg-blue-50/50 transition-colors cursor-pointer relative group">
<Upload className="w-8 h-8 text-blue-400 mx-auto mb-2" />
<p className="text-sm text-gray-500">Kattintson a feltöltéshez vagy húzza ide a fájlt</p>
<p className="text-xs text-gray-400 mt-1">(Max 1GB)</p>
<input type="file" className="absolute inset-0 w-full h-full opacity-0 cursor-pointer" title="Fájl feltöltése" />
</div>
</div>
</div>
</div>
)}
</div>
</div>
)}
{currentStep === 5 && (
<div className="space-y-8 animate-fade-in max-w-4xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Palette className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Design és stílus</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 p-8 bg-gray-50/50 rounded-3xl border border-gray-100">
<ColorPickerSection label="Főszín" selected={formData.primaryColor} onChange={(c) => setFormData(prev => ({ ...prev, primaryColor: c }))} />
<ColorPickerSection label="Mellékszín" selected={formData.secondaryColor} onChange={(c) => setFormData(prev => ({ ...prev, secondaryColor: c }))} />
<ColorPickerSection label="Kiegyensúlyozó szín" selected={formData.balanceColor} onChange={(c) => setFormData(prev => ({ ...prev, balanceColor: c }))} />
</div>
<div className="space-y-3 pt-4">
<label className={labelClass}>Weboldal stílusa:</label>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
{styleOptions.map((style) => (
<label key={style} className={`flex items-center space-x-3 cursor-pointer p-4 rounded-xl border shadow-sm transition-all ${formData.style.includes(style) ? 'border-[#4e6bff] bg-blue-50/20' : 'border-gray-200 bg-white hover:border-gray-300'}`}>
<input type="checkbox" checked={formData.style.includes(style)} onChange={() => handleCheckboxChange('style', style)} className={checkboxClass} />
<span className="text-gray-900 text-sm font-semibold">{style}</span>
</label>
))}
</div>
</div>
<div>
<label className={labelClass}>Célcsoport <span className="text-gray-400 font-normal">(opcionális)</span></label>
<input type="text" name="targetAudience" value={formData.targetAudience} onChange={handleInputChange} placeholder="Pl.: 1830 éves fiatalok, középkorú nők, vállalkozók stb." className={inputClass} />
</div>
</div>
)}
{currentStep === 6 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Zap className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Funkciók és technikai igények</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{['Kapcsolatfelvételi űrlap', 'Időpontfoglalás rendszer', 'Hírlevél-feliratkozás', 'Webshop / fizetési lehetőség', 'Blog / hírek', 'Többnyelvűség', 'Képgaléria / videógaléria', 'Google Térkép integráció', 'Chat gomb (Messenger / WhatsApp)'].map((feat) => (
<label key={feat} className={`flex items-center space-x-3 cursor-pointer p-4 rounded-xl border shadow-sm transition-all ${formData.features.includes(feat) ? 'border-[#4e6bff] bg-blue-50/20' : 'border-gray-200 bg-white hover:border-gray-300'}`}>
<input type="checkbox" checked={formData.features.includes(feat)} onChange={() => handleCheckboxChange('features', feat)} className={checkboxClass} />
<span className="text-gray-900 font-medium">{feat}</span>
</label>
))}
</div>
</div>
)}
{currentStep === 7 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Lightbulb className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Inspirációk</h3>
<p className="text-gray-500 mt-2">Segítsen megérteni az ízlését!</p>
</div>
<div className="bg-blue-50 border border-blue-100 p-5 rounded-xl text-blue-800 text-sm mb-6 flex items-start gap-3">
<div className="bg-white p-1 rounded-full"><Lightbulb className="w-4 h-4 text-[#4e6bff]" /></div>
<p>Osszon meg velünk 3 weboldalt, ami tetszik, és írja le röviden, miért (pl. színek, elrendezés, hangulat).</p>
</div>
<div className="space-y-6">
{[0, 1, 2].map((i) => (
<div key={i} className="grid grid-cols-1 md:grid-cols-2 gap-6 bg-gray-50/50 p-6 rounded-2xl border border-gray-100 hover:shadow-md transition-all">
<div>
<label className="text-xs font-bold text-gray-400 uppercase tracking-wider mb-2 block">Weboldal {i+1} URL</label>
<div className="relative">
<Globe className="absolute left-3 top-3 w-4 h-4 text-gray-400" />
<input
type="url"
value={formData.inspirations[i].url}
onChange={(e) => handleInspirationChange(i, 'url', e.target.value)}
placeholder="https://pelda.hu"
className={`${inputClass} pl-9`}
/>
</div>
</div>
<div>
<label className="text-xs font-bold text-gray-400 uppercase tracking-wider mb-2 block">Mi tetszik benne?</label>
<input
type="text"
value={formData.inspirations[i].comment}
onChange={(e) => handleInspirationChange(i, 'comment', e.target.value)}
placeholder="Színek, elrendezés, animációk..."
className={inputClass}
/>
</div>
</div>
))}
</div>
</div>
)}
{currentStep === 8 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<Settings className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Extra szolgáltatások és Megjegyzések</h3>
</div>
<div className="space-y-6">
<label className={labelClass}>Igényelt extra szolgáltatások:</label>
<div className="flex flex-wrap gap-4">
{['SEO optimalizálás', 'Szövegírás', 'Domain ügyintézés', 'Tárhely ügyintézés'].map((extra) => (
<label key={extra} className={`flex items-center space-x-3 cursor-pointer select-none p-3 rounded-lg border transition-all ${formData.extras.includes(extra) ? 'border-[#4e6bff] bg-blue-50/20' : 'border-gray-200 bg-white hover:border-gray-300'}`}>
<input type="checkbox" checked={formData.extras.includes(extra)} onChange={() => handleCheckboxChange('extras', extra)} className={checkboxClass} />
<span className="text-gray-900 font-medium">{extra}</span>
</label>
))}
</div>
{/* Dynamic Content */}
<div className="space-y-4">
{formData.extras.includes('Domain ügyintézés') && (
<div className="bg-blue-50 border border-blue-100 p-6 rounded-xl animate-fade-in">
<label className="text-sm font-semibold text-blue-900 block mb-2">Add meg a kívánt domain nevet:</label>
<div className="relative">
<Globe className="absolute left-3 top-3 w-5 h-5 text-blue-400" />
<input type="text" name="domainName" value={formData.domainName} onChange={handleInputChange} placeholder="azencegem.hu" className={`${inputClass} pl-10 border-blue-200 focus:ring-blue-300`} />
</div>
</div>
)}
{/* Domain Warning */}
{!formData.extras.includes('Domain ügyintézés') && (
<div className="bg-yellow-50 border border-yellow-100 p-6 rounded-xl flex items-start gap-4 animate-fade-in text-yellow-900 mt-2">
<div className="bg-white p-2 rounded-full shadow-sm"><Globe className="w-5 h-5 text-yellow-600" /></div>
<div className="text-sm leading-relaxed">
<strong>Figyelem:</strong> Nem jelölte be a domain ügyintézést. Kérjük győződjön meg róla, hogy rendelkezik saját domain névvel, vagy a későbbiekben tudja biztosítani a DNS beállításokat.
</div>
</div>
)}
{!formData.extras.includes('Tárhely ügyintézés') && (
<div className="bg-orange-50 border border-orange-100 p-6 rounded-xl flex items-start gap-4 animate-fade-in text-orange-900">
<div className="bg-white p-2 rounded-full shadow-sm"><Server className="w-5 h-5 text-orange-500" /></div>
<div className="text-sm leading-relaxed">
<strong>Figyelem:</strong> Mivel nem jelölte be a tárhely ügyintézést, a weboldalt átadjuk (forráskód), de az üzemeltetést és a szerver beállítását nem a MotionWeb végzi.
</div>
</div>
)}
</div>
</div>
<div className="pt-8 border-t border-gray-100">
<label className={labelClass}>Megjegyzések, további kérések</label>
<textarea name="notes" rows={5} value={formData.notes} onChange={handleInputChange} placeholder="További ötletek, kérések, megjegyzések..." className={inputClass}></textarea>
</div>
</div>
)}
{/* Step 9: Összegzés */}
{currentStep === 9 && (
<div className="space-y-8 animate-fade-in max-w-3xl mx-auto">
<div className="text-center mb-8">
<div className="w-16 h-16 bg-blue-50 rounded-2xl flex items-center justify-center mx-auto mb-4 text-[#4e6bff]">
<ClipboardCheck className="w-8 h-8" />
</div>
<h3 className="text-2xl font-bold text-gray-900">Rendelés összesítése</h3>
<p className="text-gray-500">Ellenőrizze az adatokat a véglegesítés előtt.</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 text-sm">
<div className="bg-gray-50 p-6 rounded-2xl border border-gray-200 space-y-4">
<div>
<h4 className="font-bold text-gray-400 uppercase tracking-wide text-xs mb-2">Kapcsolattartó</h4>
<p className="font-bold text-xl text-gray-900">{formData.name}</p>
<p className="text-gray-600">{formData.email}</p>
<p className="text-gray-600">{formData.phone}</p>
{formData.company && <p className="text-gray-600 font-medium mt-1">{formData.company}</p>}
</div>
<div className="pt-4 border-t border-gray-200">
<h4 className="font-bold text-gray-400 uppercase tracking-wide text-xs mb-2">Választott Csomag</h4>
<span className="inline-block bg-[#4e6bff] text-white px-4 py-1.5 rounded-full font-bold text-sm shadow-sm">{formData.package}</span>
</div>
</div>
<div className="bg-gray-50 p-6 rounded-2xl border border-gray-200 space-y-4">
<div>
<h4 className="font-bold text-gray-400 uppercase tracking-wide text-xs mb-2">Célok</h4>
<div className="flex flex-wrap gap-2">
{formData.goals.length > 0 ? formData.goals.map(g => <span key={g} className="bg-white border border-gray-200 px-3 py-1 rounded-lg text-xs font-semibold text-gray-700 shadow-sm">{g}</span>) : <span className="text-gray-400 italic">Nincs megadva</span>}
</div>
</div>
<div className="pt-4 border-t border-gray-200">
<h4 className="font-bold text-gray-400 uppercase tracking-wide text-xs mb-2">Színvilág</h4>
<div className="flex gap-3">
{formData.primaryColor && <div className="w-8 h-8 rounded-full border border-gray-200 shadow-sm" style={{background: colorOptions.find(c => c.name === formData.primaryColor)?.value}} title="Főszín"></div>}
{formData.secondaryColor && <div className="w-8 h-8 rounded-full border border-gray-200 shadow-sm" style={{background: colorOptions.find(c => c.name === formData.secondaryColor)?.value}} title="Mellékszín"></div>}
{formData.balanceColor && <div className="w-8 h-8 rounded-full border border-gray-200 shadow-sm" style={{background: colorOptions.find(c => c.name === formData.balanceColor)?.value}} title="Kiegyensúlyozó"></div>}
{!formData.primaryColor && !formData.secondaryColor && !formData.balanceColor && <span className="text-gray-400 italic">Nincs színválasztás</span>}
</div>
</div>
</div>
</div>
<div className="bg-[#4e6bff]/10 border border-[#4e6bff]/20 p-6 rounded-xl text-blue-900 text-sm">
<p className="font-bold mb-2">Mi történik a rendelés leadása után?</p>
<p className="opacity-90 leading-relaxed">
A "Rendelés leadása" gombra kattintva átirányítjuk az előlegfizetési oldalra. A sikeres tranzakciót követően kollégáink 48 órán belül felveszik Önnel a kapcsolatot a megadott elérhetőségeken a projekt indításához.
</p>
</div>
<div className="space-y-3">
<div className="flex items-start">
<div className="flex items-center h-5">
<input
id="privacy-order"
name="privacy"
type="checkbox"
required
checked={privacyAccepted}
onChange={(e) => setPrivacyAccepted(e.target.checked)}
className="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded cursor-pointer"
/>
</div>
<div className="ml-3 text-sm">
<label htmlFor="privacy-order" className="font-medium text-gray-700">
Elfogadom az <Link to="/privacy" target="_blank" className="text-primary hover:underline">Adatkezelési tájékoztatót</Link>
</label>
</div>
</div>
<div className="flex items-start">
<div className="flex items-center h-5">
<input
id="aszf-order"
name="aszf"
type="checkbox"
required
checked={aszfAccepted}
onChange={(e) => setAszfAccepted(e.target.checked)}
className="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded cursor-pointer"
/>
</div>
<div className="ml-3 text-sm">
<label htmlFor="aszf-order" className="font-medium text-gray-700">
Elfogadom az <Link to="/terms" target="_blank" className="text-primary hover:underline">Általános Szerződési Feltételeket (ÁSZF)</Link>
</label>
</div>
</div>
</div>
</div>
)}
</div>
{/* Footer Navigation */}
<div className="bg-white border-t border-gray-100 p-8 flex justify-between items-center rounded-b-2xl">
<Button
onClick={prevStep}
variant="white"
disabled={currentStep === 1 || isSubmitting}
className={`${currentStep === 1 ? 'opacity-0 pointer-events-none' : ''} border border-gray-200 text-gray-600 hover:bg-gray-50 px-6`}
>
<ArrowLeft className="w-4 h-4 mr-2" /> Vissza
</Button>
{currentStep < totalSteps ? (
<Button onClick={nextStep} className="bg-[#4e6bff] hover:bg-[#3d54cc] text-white shadow-lg shadow-blue-200 px-8 py-3 rounded-full hover:scale-105 transition-all">
Következő <ArrowRight className="w-4 h-4 ml-2" />
</Button>
) : (
<Button onClick={handleSubmit} disabled={isSubmitting} className="bg-gradient-to-r from-[#4e6bff] to-[#7c3aed] text-white shadow-xl hover:shadow-2xl hover:scale-105 transition-all px-10 py-4 text-lg rounded-full disabled:opacity-70 disabled:cursor-not-allowed">
{isSubmitting ? 'Küldés...' : (
<>Rendelés leadása <Send className="w-5 h-5 ml-2" /></>
)}
</Button>
)}
</div>
</div>
);
};