mirror of
https://github.com/Motion-Games/MotionWebStudio.git
synced 2026-04-21 09:00:53 +02:00
stripe
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import { X, Info, CheckCircle, AlertTriangle, MessageSquare, Calendar, ChevronDown, ChevronUp } from 'lucide-react';
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { X, Info, CheckCircle, AlertTriangle, MessageSquare, Calendar, ChevronDown, ChevronUp, Wallet, ArrowLeft, RefreshCw, CreditCard } from 'lucide-react';
|
||||
import { Button } from './Button';
|
||||
|
||||
interface FeedbackModalProps {
|
||||
@@ -7,11 +8,13 @@ interface FeedbackModalProps {
|
||||
onClose: () => void;
|
||||
onSubmit: (feedbackData: any) => Promise<void>;
|
||||
loading: boolean;
|
||||
order?: any;
|
||||
}
|
||||
|
||||
export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, onSubmit, loading }) => {
|
||||
export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, onSubmit, loading, order }) => {
|
||||
// --- STATE ---
|
||||
const [mainDecision, setMainDecision] = useState<'approved' | 'minor' | 'major' | null>(null);
|
||||
const [showPayment, setShowPayment] = useState(false);
|
||||
|
||||
// Approval Flow
|
||||
const [approvalConfirmed, setApprovalConfirmed] = useState(false);
|
||||
@@ -38,8 +41,28 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
|
||||
|
||||
const [revisionConfirmed, setRevisionConfirmed] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setMainDecision(null);
|
||||
setShowPayment(false);
|
||||
setApprovalConfirmed(false);
|
||||
setRevisionConfirmed(false);
|
||||
// Reset other fields if needed
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
if (!isOpen) return null;
|
||||
|
||||
// --- LOGIC ---
|
||||
const paymentDetails = order?.details?.payment_summary;
|
||||
const totalAmount = paymentDetails?.total || 0;
|
||||
const advanceAmount = paymentDetails?.advance || 0;
|
||||
const remainingAmount = paymentDetails?.remaining || 0;
|
||||
const isCustomPrice = paymentDetails?.is_custom;
|
||||
|
||||
// We show payment step ONLY if Approved AND there is a remaining amount AND it's not custom price (unless handled)
|
||||
const shouldShowPaymentStep = mainDecision === 'approved' && remainingAmount > 0 && !isCustomPrice;
|
||||
|
||||
// --- HANDLERS ---
|
||||
const handleCheckbox = (
|
||||
currentList: string[],
|
||||
@@ -71,7 +94,8 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
|
||||
decision: mainDecision,
|
||||
submittedAt: new Date().toISOString(),
|
||||
approval: mainDecision === 'approved' ? {
|
||||
confirmed: approvalConfirmed
|
||||
confirmed: approvalConfirmed,
|
||||
paymentComplete: showPayment // Flag that payment step was shown
|
||||
} : null,
|
||||
revision: isRevision ? {
|
||||
design: { selected: designCheckboxes, comment: designText },
|
||||
@@ -88,7 +112,12 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
|
||||
onSubmit(feedbackData);
|
||||
};
|
||||
|
||||
const handleProceedToPayment = () => {
|
||||
setShowPayment(true);
|
||||
};
|
||||
|
||||
const commonInputStyles = "w-full p-4 border border-gray-300 rounded-xl text-sm font-medium text-black placeholder-gray-400 focus:ring-4 focus:ring-primary/10 focus:border-primary outline-none bg-white transition-all shadow-sm";
|
||||
const formatPrice = (num: number) => num.toLocaleString('hu-HU') + ' Ft';
|
||||
|
||||
const renderFeedbackCategory = (
|
||||
title: string,
|
||||
@@ -133,156 +162,232 @@ export const FeedbackModal: React.FC<FeedbackModalProps> = ({ isOpen, onClose, o
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4 bg-gray-900/75 backdrop-blur-sm overflow-y-auto">
|
||||
<div className="bg-white rounded-3xl shadow-2xl w-full max-w-3xl flex flex-col my-8 relative animate-fade-in-up border border-white/20">
|
||||
<div className="bg-white rounded-3xl shadow-2xl w-full max-w-3xl flex flex-col my-8 relative animate-fade-in-up border border-white/20 min-h-[600px]">
|
||||
|
||||
<button onClick={onClose} className="absolute top-6 right-6 p-2 hover:bg-gray-100 rounded-full transition-colors z-10 bg-white shadow-sm border border-gray-100">
|
||||
<X className="w-5 h-5 text-gray-500" />
|
||||
</button>
|
||||
|
||||
<div className="p-8 border-b border-gray-100 bg-gradient-to-r from-blue-50/50 to-purple-50/50 rounded-t-3xl">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="bg-white p-3 rounded-2xl shadow-md text-primary border border-gray-100">
|
||||
<MessageSquare className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-2xl font-black text-gray-900 tracking-tighter">Visszajelzés a Weboldalról</h2>
|
||||
<p className="text-sm text-gray-500 font-medium mt-1">A bemutató verzió alapján kérjük jelezd, ha valamit módosítanál.</p>
|
||||
</div>
|
||||
{showPayment ? (
|
||||
/* PAYMENT SUMMARY VIEW */
|
||||
<div className="flex flex-col h-full animate-fade-in">
|
||||
<div className="p-8 border-b border-gray-100 bg-gradient-to-r from-blue-50/50 to-purple-50/50 rounded-t-3xl">
|
||||
<div className="flex items-center gap-4">
|
||||
<button onClick={() => setShowPayment(false)} className="p-2 bg-white rounded-xl shadow-sm border border-gray-100 hover:bg-gray-50 transition-colors text-gray-600">
|
||||
<ArrowLeft className="w-5 h-5" />
|
||||
</button>
|
||||
<div>
|
||||
<h2 className="text-2xl font-black text-gray-900 tracking-tighter">Véglegesítés & Fizetés</h2>
|
||||
<p className="text-sm text-gray-500 font-medium mt-1">A fennmaradó összeg rendezése a projekt lezárásához.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8 md:p-12 flex-grow space-y-10">
|
||||
<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 border border-green-100">
|
||||
<Wallet className="w-10 h-10" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">Projekt Elszámolás</h3>
|
||||
<p className="text-gray-500 text-sm max-w-md mx-auto">A demó oldal jóváhagyásával a projekt a befejező szakaszba lép. Kérjük, egyenlítse ki a fennmaradó összeget.</p>
|
||||
</div>
|
||||
|
||||
<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-lg font-bold text-gray-900">{formatPrice(totalAmount)}</p>
|
||||
</div>
|
||||
<div className="bg-green-50/50 p-6 rounded-[24px] border border-green-100 flex flex-col items-center text-center">
|
||||
<p className="text-[10px] font-black text-green-600 uppercase tracking-widest mb-2">Már Befizetve (Előleg)</p>
|
||||
<p className="text-lg font-bold text-green-700">{formatPrice(advanceAmount)}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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">Most Fizetendő (Fennmaradó)</p>
|
||||
<div className="text-4xl md:text-5xl font-black text-primary mb-6 tracking-tighter">
|
||||
{formatPrice(remainingAmount)}
|
||||
</div>
|
||||
<div className="flex justify-center">
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={loading}
|
||||
className="font-black uppercase text-[10px] tracking-widest px-12 py-4 h-auto shadow-2xl shadow-primary/40"
|
||||
>
|
||||
{loading ? <RefreshCw className="w-4 h-4 animate-spin mr-2" /> : <CreditCard className="w-4 h-4 mr-2" />}
|
||||
FIZETÉS & JÓVÁHAGYOM
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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 befizetés után a rendszer automatikusan kiállítja a végszámlát és elküldi e-mailben. A fejlesztő csapat értesítést kap a jóváhagyásról és megkezdi a végleges élesítést.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8 md:p-10 space-y-10">
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-gray-900 mb-5 flex items-center gap-2">
|
||||
Döntés a továbblépésről <span className="text-red-500">*</span>
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{[
|
||||
{ id: 'approved', label: 'Igen, jóváhagyom a terveket', color: 'green', icon: '✅' },
|
||||
{ id: 'minor', label: 'Alapvetően jó, de kisebb javításokat kérek', color: 'yellow', icon: '🔧' },
|
||||
{ id: 'major', label: 'Nem megfelelő, jelentős módosításra van szükség', color: 'red', icon: '❌' }
|
||||
].map(opt => (
|
||||
<label key={opt.id} className={`flex items-center p-5 border-2 rounded-2xl cursor-pointer transition-all ${mainDecision === opt.id ? `border-${opt.color}-500 bg-${opt.color}-50 shadow-lg ring-1 ring-${opt.color}-500` : 'border-gray-100 hover:border-gray-200'}`}>
|
||||
<input
|
||||
type="radio"
|
||||
name="decision"
|
||||
checked={mainDecision === opt.id}
|
||||
onChange={() => setMainDecision(opt.id as any)}
|
||||
className={`w-6 h-6 text-${opt.color}-600 focus:ring-${opt.color}-500 border-gray-300`}
|
||||
/>
|
||||
<span className="ml-4 font-bold text-gray-900">{opt.icon} {opt.label}</span>
|
||||
</label>
|
||||
))}
|
||||
) : (
|
||||
/* STANDARD FEEDBACK FORM */
|
||||
<>
|
||||
<div className="p-8 border-b border-gray-100 bg-gradient-to-r from-blue-50/50 to-purple-50/50 rounded-t-3xl">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="bg-white p-3 rounded-2xl shadow-md text-primary border border-gray-100">
|
||||
<MessageSquare className="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="text-2xl font-black text-gray-900 tracking-tighter">Visszajelzés a Weboldalról</h2>
|
||||
<p className="text-sm text-gray-500 font-medium mt-1">A bemutató verzió alapján kérjük jelezd, ha valamit módosítanál.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{mainDecision === 'approved' && (
|
||||
<div className="animate-fade-in bg-green-50 p-6 rounded-2xl border-2 border-green-200 shadow-inner">
|
||||
<h3 className="text-green-900 font-black mb-4 flex items-center gap-2 uppercase text-sm tracking-widest">
|
||||
<CheckCircle className="w-5 h-5" /> Megerősítés
|
||||
</h3>
|
||||
<label className="flex items-start cursor-pointer group">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={approvalConfirmed}
|
||||
onChange={(e) => setApprovalConfirmed(e.target.checked)}
|
||||
className="mt-1 w-6 h-6 text-green-600 rounded-lg focus:ring-green-500 border-green-300"
|
||||
/>
|
||||
<span className="ml-4 text-sm text-green-800 font-bold leading-relaxed">
|
||||
Tudomásul veszem, hogy a jóváhagyás után a végleges fejlesztés megkezdődik a tervek alapján.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
<div className="p-8 md:p-10 space-y-10 flex-grow overflow-y-auto">
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-gray-900 mb-5 flex items-center gap-2">
|
||||
Döntés a továbblépésről <span className="text-red-500">*</span>
|
||||
</h3>
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{[
|
||||
{ id: 'approved', label: 'Igen, jóváhagyom a terveket', color: 'green', icon: '✅' },
|
||||
{ id: 'minor', label: 'Alapvetően jó, de kisebb javításokat kérek', color: 'yellow', icon: '🔧' },
|
||||
{ id: 'major', label: 'Nem megfelelő, jelentős módosításra van szükség', color: 'red', icon: '❌' }
|
||||
].map(opt => (
|
||||
<label key={opt.id} className={`flex items-center p-5 border-2 rounded-2xl cursor-pointer transition-all ${mainDecision === opt.id ? `border-${opt.color}-500 bg-${opt.color}-50 shadow-lg ring-1 ring-${opt.color}-500` : 'border-gray-100 hover:border-gray-200'}`}>
|
||||
<input
|
||||
type="radio"
|
||||
name="decision"
|
||||
checked={mainDecision === opt.id}
|
||||
onChange={() => setMainDecision(opt.id as any)}
|
||||
className={`w-6 h-6 text-${opt.color}-600 focus:ring-${opt.color}-500 border-gray-300`}
|
||||
/>
|
||||
<span className="ml-4 font-bold text-gray-900">{opt.icon} {opt.label}</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isRevision && (
|
||||
<div className="animate-fade-in space-y-8 border-t border-gray-100 pt-10">
|
||||
|
||||
{renderFeedbackCategory(
|
||||
"Dizájn módosítások",
|
||||
["Színek", "Betűtípusok", "Elrendezés", "Képek / Illusztrációk", "Nem szeretnék dizájn módosítást"],
|
||||
designCheckboxes, setDesignCheckboxes,
|
||||
designText, setDesignText,
|
||||
"Írd le pontosan, mit változtatnál a megjelenésen..."
|
||||
{mainDecision === 'approved' && (
|
||||
<div className="animate-fade-in bg-green-50 p-6 rounded-2xl border-2 border-green-200 shadow-inner">
|
||||
<h3 className="text-green-900 font-black mb-4 flex items-center gap-2 uppercase text-sm tracking-widest">
|
||||
<CheckCircle className="w-5 h-5" /> Megerősítés
|
||||
</h3>
|
||||
<label className="flex items-start cursor-pointer group">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={approvalConfirmed}
|
||||
onChange={(e) => setApprovalConfirmed(e.target.checked)}
|
||||
className="mt-1 w-6 h-6 text-green-600 rounded-lg focus:ring-green-500 border-green-300"
|
||||
/>
|
||||
<span className="ml-4 text-sm text-green-800 font-bold leading-relaxed">
|
||||
Tudomásul veszem, hogy a jóváhagyással elfogadom a jelenlegi állapotot, és a folyamat a végleges elszámolással folytatódik.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{renderFeedbackCategory(
|
||||
"Tartalmi változtatások",
|
||||
["Szövegek stílusa", "Adatok pontosítása", "Hiányzó tartalom", "Nem szeretnék tartalmi módosítást"],
|
||||
contentCheckboxes, setContentCheckboxes,
|
||||
contentText, setContentText,
|
||||
"Írd le a szöveges módosításokat..."
|
||||
{isRevision && (
|
||||
<div className="animate-fade-in space-y-8 border-t border-gray-100 pt-10">
|
||||
|
||||
{renderFeedbackCategory(
|
||||
"Dizájn módosítások",
|
||||
["Színek", "Betűtípusok", "Elrendezés", "Képek / Illusztrációk", "Nem szeretnék dizájn módosítást"],
|
||||
designCheckboxes, setDesignCheckboxes,
|
||||
designText, setDesignText,
|
||||
"Írd le pontosan, mit változtatnál a megjelenésen..."
|
||||
)}
|
||||
|
||||
{renderFeedbackCategory(
|
||||
"Tartalmi változtatások",
|
||||
["Szövegek stílusa", "Adatok pontosítása", "Hiányzó tartalom", "Nem szeretnék tartalmi módosítást"],
|
||||
contentCheckboxes, setContentCheckboxes,
|
||||
contentText, setContentText,
|
||||
"Írd le a szöveges módosításokat..."
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-black text-gray-900 mb-3 uppercase tracking-widest">Mi a legfontosabb kérésed? <span className="text-red-500">*</span></h3>
|
||||
<textarea
|
||||
value={priorityText}
|
||||
onChange={(e) => setPriorityText(e.target.value)}
|
||||
className={commonInputStyles}
|
||||
rows={2}
|
||||
placeholder="A legkritikusabb pont, amin változtatni kell..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-black text-gray-900 mb-3 uppercase tracking-widest">Egyéb észrevételek</h3>
|
||||
<textarea
|
||||
value={extraNotes}
|
||||
onChange={(e) => setExtraNotes(e.target.value)}
|
||||
className={commonInputStyles}
|
||||
rows={4}
|
||||
placeholder="Bármi egyéb megjegyzés..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div className="bg-yellow-50 p-6 rounded-2xl border-2 border-yellow-200 shadow-inner">
|
||||
<label className="flex items-start cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={revisionConfirmed}
|
||||
onChange={(e) => setRevisionConfirmed(e.target.checked)}
|
||||
className="mt-1 w-6 h-6 text-yellow-600 rounded-lg focus:ring-yellow-500 border-yellow-300"
|
||||
/>
|
||||
<span className="ml-4 text-sm text-yellow-900 font-bold leading-relaxed">
|
||||
Tudomásul veszem, hogy a kért módosítások feldolgozása után kollégáik keresni fognak az újabb verzióval.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="p-8 border-t border-gray-100 bg-gray-50/50 rounded-b-3xl flex flex-col sm:flex-row justify-end gap-4">
|
||||
<Button variant="white" onClick={onClose} disabled={loading} className="px-10 border-gray-200">Mégse</Button>
|
||||
|
||||
{mainDecision === 'approved' && (
|
||||
shouldShowPaymentStep ? (
|
||||
<Button
|
||||
onClick={handleProceedToPayment}
|
||||
disabled={loading || !approvalConfirmed}
|
||||
className="bg-primary hover:bg-primary-dark text-white font-black uppercase tracking-widest px-10 shadow-lg shadow-primary/20"
|
||||
>
|
||||
Tovább a fizetéshez
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={loading || !approvalConfirmed}
|
||||
className="bg-green-600 hover:bg-green-700 text-white font-black uppercase tracking-widest px-10 shadow-lg shadow-green-200"
|
||||
>
|
||||
{loading ? 'Küldés...' : 'Végleges Jóváhagyás'}
|
||||
</Button>
|
||||
)
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-black text-gray-900 mb-3 uppercase tracking-widest">Mi a legfontosabb kérésed? <span className="text-red-500">*</span></h3>
|
||||
<textarea
|
||||
value={priorityText}
|
||||
onChange={(e) => setPriorityText(e.target.value)}
|
||||
className={commonInputStyles}
|
||||
rows={2}
|
||||
placeholder="A legkritikusabb pont, amin változtatni kell..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-sm font-black text-gray-900 mb-3 uppercase tracking-widest">Egyéb észrevételek</h3>
|
||||
<textarea
|
||||
value={extraNotes}
|
||||
onChange={(e) => setExtraNotes(e.target.value)}
|
||||
className={commonInputStyles}
|
||||
rows={4}
|
||||
placeholder="Bármi egyéb megjegyzés..."
|
||||
></textarea>
|
||||
</div>
|
||||
|
||||
<div className="bg-yellow-50 p-6 rounded-2xl border-2 border-yellow-200 shadow-inner">
|
||||
<label className="flex items-start cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={revisionConfirmed}
|
||||
onChange={(e) => setRevisionConfirmed(e.target.checked)}
|
||||
className="mt-1 w-6 h-6 text-yellow-600 rounded-lg focus:ring-yellow-500 border-yellow-300"
|
||||
/>
|
||||
<span className="ml-4 text-sm text-yellow-900 font-bold leading-relaxed">
|
||||
Tudomásul veszem, hogy a kért módosítások feldolgozása után kollégáik keresni fognak az újabb verzióval.
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
{isRevision && (
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={loading || !revisionConfirmed || !priorityText.trim()}
|
||||
className="font-black uppercase tracking-widest px-10 shadow-lg shadow-primary/20"
|
||||
>
|
||||
{loading ? 'Küldés...' : 'Visszajelzés Elküldése'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!mainDecision && (
|
||||
<Button disabled className="opacity-50 cursor-not-allowed font-black uppercase tracking-widest px-10">
|
||||
Válasszon opciót
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="p-8 border-t border-gray-100 bg-gray-50/50 rounded-b-3xl flex flex-col sm:flex-row justify-end gap-4">
|
||||
<Button variant="white" onClick={onClose} disabled={loading} className="px-10 border-gray-200">Mégse</Button>
|
||||
|
||||
{mainDecision === 'approved' && (
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={loading || !approvalConfirmed}
|
||||
className="bg-green-600 hover:bg-green-700 text-white font-black uppercase tracking-widest px-10 shadow-lg shadow-green-200"
|
||||
>
|
||||
{loading ? 'Küldés...' : 'Végleges Jóváhagyás'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{isRevision && (
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={loading || !revisionConfirmed || !priorityText.trim()}
|
||||
className="font-black uppercase tracking-widest px-10 shadow-lg shadow-primary/20"
|
||||
>
|
||||
{loading ? 'Küldés...' : 'Visszajelzés Elküldése'}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{!mainDecision && (
|
||||
<Button disabled className="opacity-50 cursor-not-allowed font-black uppercase tracking-widest px-10">
|
||||
Válasszon opciót
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,48 +23,39 @@ export const ProfileCompleter: React.FC = () => {
|
||||
const checkProfile = async () => {
|
||||
setChecking(true);
|
||||
|
||||
// --- DEMO MODE ---
|
||||
if (!isSupabaseConfigured) {
|
||||
const checkMetadataFallback = () => {
|
||||
const meta = user.user_metadata || {};
|
||||
if (!meta.first_name || !meta.last_name || !meta.date_of_birth) {
|
||||
const hasRequiredData = meta.first_name && meta.last_name && meta.date_of_birth;
|
||||
|
||||
if (!hasRequiredData) {
|
||||
setIsOpen(true);
|
||||
if (meta.first_name) setFirstName(meta.first_name);
|
||||
if (meta.last_name) setLastName(meta.last_name);
|
||||
if (meta.date_of_birth) setDateOfBirth(meta.date_of_birth);
|
||||
if (meta.first_name) setFirstName(meta.first_name);
|
||||
if (meta.last_name) setLastName(meta.last_name);
|
||||
if (meta.date_of_birth) setDateOfBirth(meta.date_of_birth);
|
||||
}
|
||||
};
|
||||
|
||||
if (!isSupabaseConfigured) {
|
||||
checkMetadataFallback();
|
||||
setChecking(false);
|
||||
return;
|
||||
}
|
||||
// -----------------
|
||||
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
const { data, error: fetchError } = await supabase
|
||||
.from('profiles')
|
||||
.select('first_name, last_name, date_of_birth')
|
||||
.eq('id', user.id)
|
||||
.maybeSingle();
|
||||
|
||||
if (error) {
|
||||
console.error('Error checking profile:', error.message || error);
|
||||
// If DB check fails, fallback to metadata to see if we should block the user.
|
||||
// This prevents locking the user out if the DB is temporarily unavailable or misconfigured,
|
||||
// provided they have the data in their auth metadata.
|
||||
const meta = user.user_metadata || {};
|
||||
const hasMetadata = meta.first_name && meta.last_name && meta.date_of_birth;
|
||||
|
||||
if (!hasMetadata) {
|
||||
setIsOpen(true);
|
||||
if (meta.first_name) setFirstName(meta.first_name);
|
||||
if (meta.last_name) setLastName(meta.last_name);
|
||||
if (meta.date_of_birth) setDateOfBirth(meta.date_of_birth);
|
||||
}
|
||||
if (fetchError) {
|
||||
// Ha hálózati hiba van (pl. adblocker vagy CORS), a metadata-ra hagyatkozunk csendben
|
||||
checkMetadataFallback();
|
||||
return;
|
||||
}
|
||||
|
||||
// If no profile exists, or names/dob are missing
|
||||
if (!data || !data.first_name || !data.last_name || !data.date_of_birth) {
|
||||
setIsOpen(true);
|
||||
// Pre-fill if partial data exists
|
||||
if (data?.first_name) setFirstName(data.first_name);
|
||||
else if (user.user_metadata?.first_name) setFirstName(user.user_metadata.first_name);
|
||||
|
||||
@@ -75,7 +66,13 @@ export const ProfileCompleter: React.FC = () => {
|
||||
else if (user.user_metadata?.date_of_birth) setDateOfBirth(user.user_metadata.date_of_birth);
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Unexpected error in ProfileCompleter:', err);
|
||||
// Hálózat-specifikus hibák esetén nem logolunk noisyt
|
||||
if (err instanceof TypeError && err.message.includes('fetch')) {
|
||||
checkMetadataFallback();
|
||||
} else {
|
||||
console.debug('Supabase connection issue, using metadata fallback.');
|
||||
checkMetadataFallback();
|
||||
}
|
||||
} finally {
|
||||
setChecking(false);
|
||||
}
|
||||
@@ -96,11 +93,8 @@ export const ProfileCompleter: React.FC = () => {
|
||||
}
|
||||
|
||||
try {
|
||||
// --- DEMO MODE UPDATE ---
|
||||
if (!isSupabaseConfigured && user) {
|
||||
await new Promise(resolve => setTimeout(resolve, 800)); // Fake delay
|
||||
|
||||
// Update local storage session
|
||||
await new Promise(resolve => setTimeout(resolve, 800));
|
||||
const storedSession = localStorage.getItem('demo_user_session');
|
||||
if (storedSession) {
|
||||
const parsed = JSON.parse(storedSession);
|
||||
@@ -111,15 +105,13 @@ export const ProfileCompleter: React.FC = () => {
|
||||
date_of_birth: dateOfBirth
|
||||
};
|
||||
localStorage.setItem('demo_user_session', JSON.stringify(parsed));
|
||||
refreshDemoUser(); // Refresh context
|
||||
refreshDemoUser();
|
||||
}
|
||||
setIsOpen(false);
|
||||
return;
|
||||
}
|
||||
// ------------------------
|
||||
|
||||
if (user) {
|
||||
// 1. Update Profile Table
|
||||
const { error: dbError } = await supabase
|
||||
.from('profiles')
|
||||
.upsert({
|
||||
@@ -133,7 +125,6 @@ export const ProfileCompleter: React.FC = () => {
|
||||
|
||||
if (dbError) throw dbError;
|
||||
|
||||
// 2. Update Auth Metadata (optional, but good for consistency)
|
||||
await supabase.auth.updateUser({
|
||||
data: {
|
||||
first_name: firstName,
|
||||
@@ -143,8 +134,6 @@ export const ProfileCompleter: React.FC = () => {
|
||||
});
|
||||
|
||||
setIsOpen(false);
|
||||
// We do not reload here to avoid infinite loops if checks fail on reload.
|
||||
// The state close is enough.
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('Error updating profile:', err);
|
||||
@@ -164,9 +153,7 @@ export const ProfileCompleter: React.FC = () => {
|
||||
<User className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold">Hiányzó Adatok</h2>
|
||||
<p className="text-blue-100 text-sm mt-2">
|
||||
Kérjük, a folytatáshoz adja meg a hiányzó adatait.
|
||||
</p>
|
||||
<p className="text-blue-100 text-sm mt-2">Kérjük, a folytatáshoz adja meg a hiányzó adatait.</p>
|
||||
</div>
|
||||
|
||||
<div className="p-8">
|
||||
@@ -177,71 +164,33 @@ export const ProfileCompleter: React.FC = () => {
|
||||
<span>{error}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="comp_lastname" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Vezetéknév
|
||||
</label>
|
||||
<input
|
||||
id="comp_lastname"
|
||||
type="text"
|
||||
value={lastName}
|
||||
onChange={(e) => setLastName(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900"
|
||||
placeholder="Kovács"
|
||||
required
|
||||
/>
|
||||
<label htmlFor="comp_lastname" className="block text-sm font-medium text-gray-700 mb-1">Vezetéknév</label>
|
||||
<input id="comp_lastname" type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900" placeholder="Kovács" required />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="comp_firstname" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Keresztnév
|
||||
</label>
|
||||
<input
|
||||
id="comp_firstname"
|
||||
type="text"
|
||||
value={firstName}
|
||||
onChange={(e) => setFirstName(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900"
|
||||
placeholder="János"
|
||||
required
|
||||
/>
|
||||
<label htmlFor="comp_firstname" className="block text-sm font-medium text-gray-700 mb-1">Keresztnév</label>
|
||||
<input id="comp_firstname" type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900" placeholder="János" required />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="comp_dob" className="block text-sm font-medium text-gray-700 mb-1">
|
||||
Születési dátum
|
||||
</label>
|
||||
<label htmlFor="comp_dob" className="block text-sm font-medium text-gray-700 mb-1">Születési dátum</label>
|
||||
<div className="relative">
|
||||
<input
|
||||
id="comp_dob"
|
||||
type="date"
|
||||
value={dateOfBirth}
|
||||
onChange={(e) => setDateOfBirth(e.target.value)}
|
||||
className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900"
|
||||
required
|
||||
/>
|
||||
<input id="comp_dob" type="date" value={dateOfBirth} onChange={(e) => setDateOfBirth(e.target.value)} className="w-full px-4 py-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-primary focus:border-transparent outline-none transition-all bg-white text-gray-900" required />
|
||||
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
|
||||
<Calendar className="h-5 w-5 text-gray-400" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<Button type="submit" fullWidth disabled={loading} className="flex justify-center items-center">
|
||||
{loading ? 'Mentés...' : (
|
||||
<>
|
||||
Adatok Mentése <Save className="ml-2 w-4 h-4" />
|
||||
</>
|
||||
<>Adatok Mentése <Save className="ml-2 w-4 h-4" /></>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-center text-gray-500">
|
||||
Ezekre az adatokra a számlázáshoz és a kapcsolattartáshoz van szükségünk.
|
||||
</p>
|
||||
<p className="text-xs text-center text-gray-500">Ezekre az adatokra a számlázáshoz és a kapcsolattartáshoz van szükségünk.</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<html lang="hu">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="https://picsum.photos/id/48/32/32" />
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='grad' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' style='stop-color:%237c3aed;stop-opacity:1' /%3E%3Cstop offset='100%25' style='stop-color:%233b82f6;stop-opacity:1' /%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='8' fill='url(%23grad)'/%3E%3Cpath d='M22 20l4-4-4-4M10 12l-4 4 4 4M18.5 8l-5 16' stroke='white' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/%3E%3C/svg%3E" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Motion Web Stúdió - Professzionális Webfejlesztés</title>
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ export const defaultPlans: ProductPackage[] = [
|
||||
{
|
||||
id: 'start',
|
||||
name: "Landing Page",
|
||||
price: "190.000 Ft-tól",
|
||||
price: "190.000 Ft",
|
||||
total_price: 190000,
|
||||
advance_price: 40000,
|
||||
desc: "Ideális induló vállalkozásoknak és személyes brandeknek.",
|
||||
features: [
|
||||
"Egyoldalas Landing Page",
|
||||
@@ -20,7 +22,9 @@ export const defaultPlans: ProductPackage[] = [
|
||||
{
|
||||
id: 'pro',
|
||||
name: "Pro Web",
|
||||
price: "350.000 Ft-tól",
|
||||
price: "350.000 Ft",
|
||||
total_price: 350000,
|
||||
advance_price: 80000,
|
||||
desc: "A legnépszerűbb választás kis- és középvállalkozások számára.",
|
||||
features: [
|
||||
"Max 5 aloldal (Rólunk, Szolgáltatások...)",
|
||||
@@ -38,6 +42,9 @@ export const defaultPlans: ProductPackage[] = [
|
||||
id: 'enterprise',
|
||||
name: "Enterprise",
|
||||
price: "Egyedi árazás",
|
||||
total_price: 0,
|
||||
advance_price: 0,
|
||||
is_custom_price: true,
|
||||
desc: "Komplex rendszerek és webáruházak nagyvállalati igényekre.",
|
||||
features: [
|
||||
"Korlátlan aloldalak",
|
||||
|
||||
1559
pages/Admin.tsx
1559
pages/Admin.tsx
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,13 @@
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { Button } from '../components/Button';
|
||||
import { LogOut, User, Settings as SettingsIcon, CreditCard, Layout, Cake, ShieldAlert, Clock, Activity, CheckCircle, XCircle, MessageSquare, ArrowRight, Edit2, Download, FileText, ExternalLink, History, RefreshCw } from 'lucide-react';
|
||||
import { LogOut, User, Settings as SettingsIcon, CreditCard, Layout, Cake, ShieldAlert, Clock, Activity, CheckCircle, XCircle, MessageSquare, ArrowRight, Edit2, Download, FileText, ExternalLink, History, RefreshCw, FileDown, ShieldCheck, Calendar } from 'lucide-react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { supabase, isSupabaseConfigured } from '../lib/supabaseClient';
|
||||
import { SettingsModal } from '../components/SettingsModal';
|
||||
import { FeedbackModal } from '../components/FeedbackModal';
|
||||
import { Invoice } from '../types';
|
||||
import { Invoice, MaintenanceSubscription } from '../types';
|
||||
|
||||
interface UserProfile {
|
||||
id: string;
|
||||
@@ -22,6 +23,14 @@ interface OrderHistoryEntry {
|
||||
changed_at: string;
|
||||
}
|
||||
|
||||
interface Bill {
|
||||
id: string;
|
||||
order_id: string;
|
||||
type: 'advance' | 'final';
|
||||
file_url: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface UserOrder {
|
||||
id: string;
|
||||
created_at: string;
|
||||
@@ -31,6 +40,8 @@ interface UserOrder {
|
||||
displayId?: string;
|
||||
details?: any;
|
||||
history?: OrderHistoryEntry[];
|
||||
bills?: Bill[];
|
||||
subscription?: MaintenanceSubscription;
|
||||
}
|
||||
|
||||
export const Dashboard: React.FC = () => {
|
||||
@@ -60,6 +71,34 @@ export const Dashboard: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchOrderBills = async (orderId: string) => {
|
||||
if (!isSupabaseConfigured) return [];
|
||||
try {
|
||||
const { data } = await supabase
|
||||
.from('bills')
|
||||
.select('*')
|
||||
.eq('order_id', orderId)
|
||||
.order('created_at', { ascending: false });
|
||||
return data || [];
|
||||
} catch (e) {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
const fetchSubscription = async (orderId: string) => {
|
||||
if (!isSupabaseConfigured) return undefined;
|
||||
try {
|
||||
const { data } = await supabase
|
||||
.from('maintenance_subscriptions')
|
||||
.select('*')
|
||||
.eq('order_id', orderId)
|
||||
.maybeSingle();
|
||||
return data as MaintenanceSubscription | undefined;
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const fetchData = async () => {
|
||||
if (!user) return;
|
||||
setLoadingOrders(true);
|
||||
@@ -67,7 +106,25 @@ export const Dashboard: React.FC = () => {
|
||||
if (!isSupabaseConfigured) {
|
||||
const meta = user.user_metadata || {};
|
||||
setProfile({ id: user.id, email: user.email || '', first_name: meta.first_name || '', last_name: meta.last_name || '', date_of_birth: meta.date_of_birth || '1990-01-01' });
|
||||
setOrders([{ id: 'demo-order-1', created_at: new Date().toISOString(), package: 'Pro Web', status: 'pending_feedback', amount: '350.000 Ft', displayId: 'DEMO-123', details: { demoUrl: 'https://example.com' }, history: [{ id: 'h1', status: 'new', changed_at: new Date().toISOString() }] }]);
|
||||
setOrders([{
|
||||
id: 'demo-order-1',
|
||||
created_at: new Date().toISOString(),
|
||||
package: 'Pro Web',
|
||||
status: 'pending_feedback',
|
||||
amount: '350.000 Ft',
|
||||
displayId: 'DEMO-123',
|
||||
details: {
|
||||
demoUrl: 'https://example.com',
|
||||
payment_summary: {
|
||||
total: 350000,
|
||||
advance: 80000,
|
||||
remaining: 270000,
|
||||
currency: 'HUF'
|
||||
}
|
||||
},
|
||||
history: [{ id: 'h1', status: 'new', changed_at: new Date().toISOString() }],
|
||||
bills: []
|
||||
}]);
|
||||
setLoadingOrders(false);
|
||||
return;
|
||||
}
|
||||
@@ -81,10 +138,14 @@ export const Dashboard: React.FC = () => {
|
||||
if (orderData) {
|
||||
const enrichedOrders = await Promise.all(orderData.map(async (o) => {
|
||||
const history = await fetchOrderHistory(o.id);
|
||||
const bills = await fetchOrderBills(o.id);
|
||||
const sub = await fetchSubscription(o.id);
|
||||
return {
|
||||
...o,
|
||||
displayId: o.id.substring(0, 8).toUpperCase(),
|
||||
history: history
|
||||
history: history,
|
||||
bills: bills,
|
||||
subscription: sub
|
||||
};
|
||||
}));
|
||||
setOrders(enrichedOrders as UserOrder[]);
|
||||
@@ -130,7 +191,6 @@ export const Dashboard: React.FC = () => {
|
||||
const { data: currentOrder } = await supabase.from('orders').select('details').eq('id', selectedOrderId).single();
|
||||
const updatedDetails = { ...(currentOrder?.details || {}), latestFeedback: feedbackData, feedbackDate: new Date().toISOString() };
|
||||
|
||||
// Approved status also goes to in_progress now, admin will set to completed later
|
||||
const { error: updateError } = await supabase.from('orders').update({
|
||||
status: 'in_progress',
|
||||
details: updatedDetails
|
||||
@@ -138,7 +198,6 @@ export const Dashboard: React.FC = () => {
|
||||
|
||||
if (updateError) throw updateError;
|
||||
|
||||
// Log history
|
||||
await supabase.from('order_status_history').insert({ order_id: selectedOrderId, status: 'in_progress' });
|
||||
|
||||
await fetchData();
|
||||
@@ -166,29 +225,37 @@ export const Dashboard: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const selectedOrder = orders.find(o => o.id === selectedOrderId);
|
||||
|
||||
return (
|
||||
<div className="pt-24 bg-gray-50 min-h-screen">
|
||||
<div className="pt-24 bg-gray-50 min-h-screen pb-12">
|
||||
<SettingsModal isOpen={showSettings} onClose={() => setShowSettings(false)} userProfile={profile} onUpdate={fetchData} />
|
||||
<FeedbackModal isOpen={feedbackModalOpen} onClose={() => setFeedbackModalOpen(false)} onSubmit={handleSubmitFeedback} loading={feedbackLoading} />
|
||||
<FeedbackModal
|
||||
isOpen={feedbackModalOpen}
|
||||
onClose={() => setFeedbackModalOpen(false)}
|
||||
onSubmit={handleSubmitFeedback}
|
||||
loading={feedbackLoading}
|
||||
order={selectedOrder}
|
||||
/>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="bg-white rounded-[24px] shadow-lg border border-gray-100 overflow-hidden mb-8">
|
||||
<div className="bg-gradient-to-r from-gray-900 to-gray-800 p-8 text-white flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<div className="bg-gradient-to-r from-gray-900 to-gray-800 p-6 md:p-8 text-white flex flex-col md:flex-row justify-between items-center gap-4 text-center md:text-left">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold mb-2">Fiók Áttekintése</h1>
|
||||
<p className="text-gray-300">Üdvözöljük, {getFullName()}!</p>
|
||||
<h1 className="text-2xl md:text-3xl font-bold mb-2">Fiók Áttekintése</h1>
|
||||
<p className="text-gray-300 text-sm md:text-base">Üdvözöljük, {getFullName()}!</p>
|
||||
</div>
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full flex items-center justify-center border border-white/20">
|
||||
<div className="h-12 w-12 bg-white/10 rounded-full flex items-center justify-center border border-white/20 shrink-0">
|
||||
<User className="h-6 w-6 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="p-8">
|
||||
<div className="p-6 md:p-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-8">
|
||||
{/* ORDERS COLUMN */}
|
||||
<div className="lg:col-span-2 space-y-6">
|
||||
<div className="flex justify-between items-center">
|
||||
<h3 className="font-bold text-gray-900 flex items-center gap-2 text-xl">
|
||||
<h3 className="font-bold text-gray-900 flex items-center gap-2 text-lg md:text-xl">
|
||||
<Layout className="w-5 h-5 text-primary" /> Aktív Projektjeim
|
||||
</h3>
|
||||
</div>
|
||||
@@ -203,54 +270,112 @@ export const Dashboard: React.FC = () => {
|
||||
|
||||
return (
|
||||
<div key={order.id} className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden hover:shadow-md transition-shadow">
|
||||
<div className="p-6 flex flex-col sm:flex-row justify-between gap-6 border-b border-gray-50 bg-gray-50/30">
|
||||
<div className="p-5 md:p-6 flex flex-col sm:flex-row justify-between gap-4 border-b border-gray-50 bg-gray-50/30">
|
||||
<div>
|
||||
<p className="text-xs font-black text-primary uppercase tracking-widest mb-1">{order.package}</p>
|
||||
<h4 className="text-xl font-bold text-gray-900">ID: {order.displayId}</h4>
|
||||
<p className="text-[10px] font-black text-primary uppercase tracking-widest mb-1">{order.package}</p>
|
||||
<h4 className="text-lg md:text-xl font-bold text-gray-900">ID: {order.displayId}</h4>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
{needsFeedback && (
|
||||
<div className="flex gap-2">
|
||||
<a href={order.details?.demoUrl || '#'} target="_blank" rel="noreferrer" className="text-xs px-4 py-2 rounded-xl font-black bg-blue-600 text-white flex items-center gap-2 shadow-lg shadow-blue-200">
|
||||
<ExternalLink className="w-3 h-3" /> Demó oldal megnyitása
|
||||
<>
|
||||
<a href={order.details?.demoUrl || '#'} target="_blank" rel="noreferrer" className="flex-grow sm:flex-grow-0 text-[10px] px-4 py-2.5 rounded-xl font-black bg-blue-600 text-white flex items-center justify-center gap-2 shadow-lg shadow-blue-200">
|
||||
<ExternalLink className="w-3 h-3" /> DEMÓ MEGNYITÁSA
|
||||
</a>
|
||||
<button onClick={() => openFeedbackModal(order.id)} className="text-xs px-4 py-2 rounded-xl font-black bg-purple-100 text-purple-700 hover:bg-purple-200">
|
||||
VISSZAJELZÉS
|
||||
<button onClick={() => openFeedbackModal(order.id)} className="flex-grow sm:flex-grow-0 text-[10px] px-4 py-2.5 rounded-xl font-black bg-purple-100 text-purple-700 hover:bg-purple-200 uppercase tracking-wider">
|
||||
Visszajelzés
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{!needsFeedback && (
|
||||
<span className={`text-xs px-4 py-2 rounded-xl font-black flex items-center gap-2 ${statusConfig.color}`}>
|
||||
<statusConfig.icon className="w-4 h-4" /> {statusConfig.label.toUpperCase()}
|
||||
<span className={`text-[10px] px-4 py-2.5 rounded-xl font-black flex items-center justify-center gap-2 ${statusConfig.color} uppercase tracking-wider`}>
|
||||
<statusConfig.icon className="w-3.5 h-3.5" /> {statusConfig.label}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* PROJECT TIMELINE */}
|
||||
<div className="p-6 bg-white">
|
||||
<div className="flex items-center gap-2 mb-4 text-xs font-black text-gray-400 uppercase tracking-[0.2em]">
|
||||
<History className="w-3 h-3" /> Projekt Történet
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 relative before:absolute before:left-[7px] before:top-2 before:bottom-2 before:w-0.5 before:bg-gray-50">
|
||||
{order.history && order.history.length > 0 ? (
|
||||
order.history.map((h, idx) => (
|
||||
<div key={h.id} className="relative pl-6 flex justify-between items-center group">
|
||||
<div className={`absolute left-0 top-1.5 w-3.5 h-3.5 rounded-full border-2 border-white shadow-sm z-10 ${idx === 0 ? 'bg-primary' : 'bg-gray-200'}`}></div>
|
||||
<div className="flex flex-col">
|
||||
<span className={`text-xs font-bold ${idx === 0 ? 'text-gray-900' : 'text-gray-500'}`}>
|
||||
{getStatusConfig(h.status).label}
|
||||
</span>
|
||||
<span className="text-[10px] text-gray-400 font-medium">
|
||||
{new Date(h.changed_at).toLocaleString('hu-HU')}
|
||||
</span>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 divide-y md:divide-y-0 md:divide-x divide-gray-100">
|
||||
{/* PROJECT TIMELINE */}
|
||||
<div className="p-5 md:p-6 bg-white">
|
||||
<div className="flex items-center gap-2 mb-4 text-[10px] font-black text-gray-400 uppercase tracking-[0.2em]">
|
||||
<History className="w-3 h-3" /> Projekt Történet
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 relative before:absolute before:left-[7px] before:top-2 before:bottom-2 before:w-0.5 before:bg-gray-50">
|
||||
{order.history && order.history.length > 0 ? (
|
||||
order.history.map((h, idx) => (
|
||||
<div key={h.id} className="relative pl-6 flex justify-between items-center group">
|
||||
<div className={`absolute left-0 top-1.5 w-3.5 h-3.5 rounded-full border-2 border-white shadow-sm z-10 ${idx === 0 ? 'bg-primary' : 'bg-gray-200'}`}></div>
|
||||
<div className="flex flex-col">
|
||||
<span className={`text-xs font-bold ${idx === 0 ? 'text-gray-900' : 'text-gray-500'}`}>
|
||||
{getStatusConfig(h.status).label}
|
||||
</span>
|
||||
<span className="text-[10px] text-gray-400 font-medium">
|
||||
{new Date(h.changed_at).toLocaleString('hu-HU')}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<p className="text-xs text-gray-400 italic pl-6">Nincs korábbi bejegyzés.</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* BILLS & DOCUMENTS / MAINTENANCE */}
|
||||
<div className="p-5 md:p-6 bg-white flex flex-col justify-between">
|
||||
<div>
|
||||
<div className="flex items-center gap-2 mb-4 text-[10px] font-black text-gray-400 uppercase tracking-[0.2em]">
|
||||
<FileText className="w-3 h-3" /> Dokumentumok
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
{order.bills && order.bills.length > 0 ? (
|
||||
order.bills.map((bill) => (
|
||||
<a
|
||||
key={bill.id}
|
||||
href={bill.file_url}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="flex items-center justify-between p-3 rounded-xl border border-gray-100 hover:border-primary/30 hover:bg-purple-50/30 transition-all group"
|
||||
>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`w-8 h-8 rounded-lg flex items-center justify-center ${bill.type === 'advance' ? 'bg-blue-50 text-blue-600' : 'bg-green-50 text-green-600'}`}>
|
||||
<CreditCard className="w-4 h-4" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-bold text-gray-900">{bill.type === 'advance' ? 'Előleg számla' : 'Végszámla'}</p>
|
||||
<p className="text-[9px] text-gray-400 font-black uppercase tracking-widest">{new Date(bill.created_at).toLocaleDateString('hu-HU')}</p>
|
||||
</div>
|
||||
</div>
|
||||
<FileDown className="w-4 h-4 text-gray-300 group-hover:text-primary group-hover:translate-y-0.5 transition-all flex-shrink-0" />
|
||||
</a>
|
||||
))
|
||||
) : (
|
||||
<div className="p-4 text-center bg-gray-50/50 rounded-2xl border border-dashed border-gray-100">
|
||||
<p className="text-[10px] font-black text-gray-400 uppercase tracking-widest leading-relaxed">Még nincs számla.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Maintenance Subscription Status (If Completed) */}
|
||||
{order.subscription && (
|
||||
<div className="mt-6 pt-4 border-t border-gray-50">
|
||||
<div className="flex items-center gap-2 mb-3 text-[10px] font-black text-gray-400 uppercase tracking-[0.2em]">
|
||||
<ShieldCheck className="w-3 h-3 text-primary" /> Karbantartás
|
||||
</div>
|
||||
<div className={`p-3 rounded-xl border flex items-center justify-between ${order.subscription.status === 'overdue' ? 'bg-red-50 border-red-100' : 'bg-green-50 border-green-100'}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className={`w-4 h-4 ${order.subscription.status === 'overdue' ? 'text-red-500' : 'text-green-500'}`} />
|
||||
<div>
|
||||
<p className={`text-[10px] font-black uppercase tracking-wider ${order.subscription.status === 'overdue' ? 'text-red-700' : 'text-green-700'}`}>
|
||||
{order.subscription.status === 'active' ? 'Aktív szolgáltatás' : 'Esedékes díj'}
|
||||
</p>
|
||||
<p className="text-xs font-bold text-gray-700">Fordulónap: {new Date(order.subscription.next_billing_date).toLocaleDateString('hu-HU')}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{idx === 0 && <span className="text-[9px] font-black text-primary bg-primary/5 px-2 py-0.5 rounded uppercase tracking-tighter">Aktuális</span>}
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<p className="text-xs text-gray-400 italic pl-6">Nincs korábbi bejegyzés.</p>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -265,43 +390,36 @@ export const Dashboard: React.FC = () => {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* SETTINGS & INVOICES COLUMN */}
|
||||
<div className="space-y-8">
|
||||
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm">
|
||||
{/* SETTINGS COLUMN */}
|
||||
<div className="space-y-6 md:space-y-8">
|
||||
<div className="bg-white p-6 md:p-8 rounded-[32px] border border-gray-100 shadow-sm">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h3 className="font-bold text-gray-900">Beállítások</h3>
|
||||
<button onClick={() => setShowSettings(true)} className="p-2 hover:bg-gray-50 rounded-xl transition-colors"><SettingsIcon className="w-5 h-5 text-gray-400" /></button>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
<div className="bg-gray-50 p-4 rounded-2xl">
|
||||
<div className="bg-gray-50 p-4 rounded-2xl overflow-hidden">
|
||||
<p className="text-[10px] font-black text-gray-400 uppercase tracking-widest mb-1">E-mail</p>
|
||||
<p className="text-sm font-bold text-gray-900">{user?.email}</p>
|
||||
<p className="text-sm font-bold text-gray-900 truncate">{user?.email}</p>
|
||||
</div>
|
||||
<Button fullWidth variant="outline" size="sm" onClick={() => setShowSettings(true)}>Profil szerkesztése</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-white p-8 rounded-[32px] border border-gray-100 shadow-sm">
|
||||
<h3 className="font-bold text-gray-900 mb-6 flex items-center gap-2"><CreditCard className="w-5 h-5 text-primary" /> Számlák</h3>
|
||||
{invoices.length > 0 ? (
|
||||
<div className="space-y-3">
|
||||
{invoices.map(inv => (
|
||||
<div key={inv.id} className="flex items-center justify-between p-3 bg-gray-50 rounded-xl group hover:bg-gray-100 transition-colors">
|
||||
<div className="flex items-center gap-3">
|
||||
<FileText className="w-5 h-5 text-gray-300" />
|
||||
<span className="text-xs font-bold text-gray-700">{inv.invoice_number}</span>
|
||||
</div>
|
||||
<button className="p-2 text-gray-400 hover:text-primary"><Download className="w-4 h-4" /></button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : <p className="text-xs text-gray-400 italic text-center">Nincs számlázott tétel.</p>}
|
||||
<div className="bg-gradient-to-br from-primary/10 to-secondary/10 p-6 md:p-8 rounded-[32px] border border-primary/10 shadow-sm">
|
||||
<h3 className="font-bold text-gray-900 mb-4 flex items-center gap-2 text-lg"><CheckCircle className="w-5 h-5 text-primary" /> Ügyfélközpont</h3>
|
||||
<p className="text-xs text-gray-600 leading-relaxed mb-6">
|
||||
Bármilyen kérdése van a számlázással vagy a fejlesztéssel kapcsolatban, írjon nekünk közvetlenül.
|
||||
</p>
|
||||
<a href="mailto:motionstudiohq@gmail.com" className="block text-center py-3 bg-white border border-gray-200 rounded-xl text-xs font-black text-primary uppercase tracking-widest hover:shadow-md transition-all shadow-sm">
|
||||
Kapcsolatfelvétel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t border-gray-100 pt-6 flex justify-end">
|
||||
<Button variant="outline" onClick={handleLogout} className="border-red-200 text-red-600 hover:bg-red-50 hover:text-red-700 hover:border-red-300">
|
||||
<div className="border-t border-gray-100 pt-6 flex justify-center md:justify-end">
|
||||
<Button variant="outline" onClick={handleLogout} className="w-full md:w-auto border-red-200 text-red-600 hover:bg-red-50 hover:text-red-700 hover:border-red-300">
|
||||
<LogOut className="w-4 h-4 mr-2" /> Kijelentkezés
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
322
pages/Home.tsx
322
pages/Home.tsx
@@ -1,6 +1,7 @@
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ArrowRight, Monitor, Search, ExternalLink, Check, Star, Smartphone, PenTool } from 'lucide-react';
|
||||
import { ArrowRight, Monitor, Search, ExternalLink, Check, Star, Smartphone, PenTool, ShieldCheck, Clock, Info } from 'lucide-react';
|
||||
import { Button } from '../components/Button';
|
||||
import { ServiceCard } from '../components/ServiceCard';
|
||||
import { OrderForm } from '../components/OrderForm';
|
||||
@@ -17,11 +18,22 @@ export const Home: React.FC = () => {
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('plans')
|
||||
.select('*')
|
||||
.order('price', { ascending: true }); // Simple text ordering, ideally numerical but works for default prices somewhat
|
||||
.select('*');
|
||||
|
||||
if (!error && data && data.length > 0) {
|
||||
setPackages(data);
|
||||
const sortedData = [...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;
|
||||
});
|
||||
setPackages(sortedData);
|
||||
} else {
|
||||
const sortedDefaults = [...defaultPlans].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;
|
||||
});
|
||||
setPackages(sortedDefaults);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error fetching plans:", e);
|
||||
@@ -30,60 +42,60 @@ export const Home: React.FC = () => {
|
||||
fetchPlans();
|
||||
}, []);
|
||||
|
||||
const formatPrice = (num: number) => num.toLocaleString('hu-HU') + ' Ft';
|
||||
|
||||
return (
|
||||
<div className="overflow-x-hidden">
|
||||
{/* Hero Section */}
|
||||
<section className="relative min-h-screen flex items-center justify-center pt-20 bg-gray-900 overflow-hidden">
|
||||
<section className="relative min-h-screen flex items-center justify-center pt-20 bg-gray-900 overflow-hidden px-4">
|
||||
{/* Background Elements */}
|
||||
<div className="absolute inset-0 z-0">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-gray-900 via-[#0f172a] to-purple-900"></div>
|
||||
{/* Subtle texture overlay */}
|
||||
<div className="absolute inset-0 opacity-10 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')]"></div>
|
||||
{/* Animated glow effects */}
|
||||
<div className="absolute top-[-20%] left-[-10%] w-[500px] h-[500px] bg-purple-600/20 rounded-full blur-[100px] animate-pulse"></div>
|
||||
<div className="absolute bottom-[-20%] right-[-10%] w-[500px] h-[500px] bg-blue-600/20 rounded-full blur-[100px] animate-pulse"></div>
|
||||
<div className="absolute top-[-20%] left-[-10%] w-[300px] md:w-[500px] h-[300px] md:h-[500px] bg-purple-600/20 rounded-full blur-[80px] md:blur-[100px] animate-pulse"></div>
|
||||
<div className="absolute bottom-[-20%] right-[-10%] w-[300px] md:w-[500px] h-[300px] md:h-[500px] bg-blue-600/20 rounded-full blur-[80px] md:blur-[100px] animate-pulse"></div>
|
||||
</div>
|
||||
|
||||
<div className="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10 py-12 text-center">
|
||||
<div className="max-w-5xl mx-auto relative z-10 py-12 text-center">
|
||||
<div
|
||||
className="inline-block px-4 py-2 bg-white/5 backdrop-blur-sm rounded-full border border-white/10 animate-fade-in-up mb-8"
|
||||
className="inline-block px-4 py-2 bg-white/5 backdrop-blur-sm rounded-full border border-white/10 animate-fade-in-up mb-6 md:mb-8"
|
||||
style={{ animationDelay: '0.1s' }}
|
||||
>
|
||||
<span className="text-blue-300 font-medium text-sm tracking-wide uppercase">Innovatív Megoldások Neked</span>
|
||||
<span className="text-blue-300 font-medium text-xs md:text-sm tracking-wide uppercase">Innovatív Megoldások Neked</span>
|
||||
</div>
|
||||
|
||||
<h1
|
||||
className="text-5xl md:text-7xl lg:text-8xl font-extrabold text-white leading-tight animate-fade-in-up mb-6 tracking-tight"
|
||||
className="text-4xl sm:text-5xl md:text-7xl lg:text-8xl font-extrabold text-white leading-tight animate-fade-in-up mb-4 md:mb-6 tracking-tight"
|
||||
style={{ animationDelay: '0.2s' }}
|
||||
>
|
||||
Motion Web Stúdió
|
||||
</h1>
|
||||
|
||||
<h2
|
||||
className="text-2xl md:text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-blue-400 to-purple-400 animate-fade-in-up mb-8"
|
||||
className="text-xl sm:text-2xl md:text-4xl font-bold text-transparent bg-clip-text bg-gradient-to-r from-blue-400 to-purple-400 animate-fade-in-up mb-8"
|
||||
style={{ animationDelay: '0.3s' }}
|
||||
>
|
||||
Vigye vállalkozását a következő szintre
|
||||
</h2>
|
||||
|
||||
<p
|
||||
className="text-lg text-gray-400 max-w-2xl mx-auto leading-relaxed animate-fade-in-up mb-12"
|
||||
className="text-base md:text-lg text-gray-400 max-w-2xl mx-auto leading-relaxed animate-fade-in-up mb-10 md:mb-12 px-2"
|
||||
style={{ animationDelay: '0.5s' }}
|
||||
>
|
||||
A MotionWeb csapata prémium minőségű weboldalakat és webáruházakat fejleszt, amelyek nemcsak szépek, de vevőket is hoznak.
|
||||
</p>
|
||||
|
||||
<div
|
||||
className="flex flex-col sm:flex-row gap-5 justify-center animate-fade-in-up"
|
||||
className="flex flex-col sm:flex-row gap-4 md:gap-5 justify-center animate-fade-in-up px-4 sm:px-0"
|
||||
style={{ animationDelay: '0.7s' }}
|
||||
>
|
||||
<Link to="/#rendeles">
|
||||
<Button size="lg" className="w-full sm:w-auto shadow-lg shadow-purple-900/20">
|
||||
<Link to="/#rendeles" className="w-full sm:w-auto">
|
||||
<Button size="lg" className="w-full shadow-lg shadow-purple-900/20">
|
||||
Kezdjük el <ArrowRight className="ml-2 w-5 h-5" />
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to="/#references">
|
||||
<Button variant="outline" size="lg" className="border-white/20 text-white hover:bg-white/10 hover:border-white w-full sm:w-auto backdrop-blur-sm">
|
||||
<Link to="/#references" className="w-full sm:w-auto">
|
||||
<Button variant="outline" size="lg" className="border-white/20 text-white hover:bg-white/10 hover:border-white w-full backdrop-blur-sm">
|
||||
Referenciák
|
||||
</Button>
|
||||
</Link>
|
||||
@@ -92,19 +104,19 @@ export const Home: React.FC = () => {
|
||||
</section>
|
||||
|
||||
{/* Services Section */}
|
||||
<section id="services" className="py-24 bg-gray-50 scroll-mt-20">
|
||||
<section id="services" className="py-20 md:py-24 bg-gray-50 scroll-mt-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center max-w-3xl mx-auto mb-16">
|
||||
<h2 className="text-base font-semibold text-primary tracking-wide uppercase">Szolgáltatásaink</h2>
|
||||
<p className="mt-2 text-3xl font-extrabold text-gray-900 sm:text-4xl">
|
||||
<div className="text-center max-w-3xl mx-auto mb-12 md:mb-16">
|
||||
<h2 className="text-sm md:text-base font-semibold text-primary tracking-wide uppercase">Szolgáltatásaink</h2>
|
||||
<p className="mt-2 text-2xl sm:text-3xl md:text-4xl font-extrabold text-gray-900">
|
||||
Minden, ami a sikeres online jelenléthez kell
|
||||
</p>
|
||||
<p className="mt-4 text-xl text-gray-500">
|
||||
<p className="mt-4 text-lg md:text-xl text-gray-500 px-2">
|
||||
Teljeskörű digitális kivitelezés a tervezéstől az üzemeltetésig.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 md:gap-8">
|
||||
<ServiceCard
|
||||
title="Egyedi Weboldal"
|
||||
description="Modern, gyors és reszponzív weboldalak, amelyek tükrözik márkája értékeit."
|
||||
@@ -130,115 +142,59 @@ export const Home: React.FC = () => {
|
||||
</section>
|
||||
|
||||
{/* References Section */}
|
||||
<section id="references" className="py-24 bg-white scroll-mt-20">
|
||||
<section id="references" className="py-20 md:py-24 bg-white scroll-mt-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">Referenciák</h2>
|
||||
<p className="text-lg text-gray-600 max-w-2xl mx-auto">
|
||||
<div className="text-center mb-12 md:mb-16">
|
||||
<h2 className="text-2xl md:text-4xl font-bold text-gray-900 mb-4">Referenciák</h2>
|
||||
<p className="text-base md:text-lg text-gray-600 max-w-2xl mx-auto">
|
||||
Tekintsd meg, milyen modern és reszponzív weboldalakat készítünk ügyfeleink számára.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{/* Card 1: SweetCraving */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-8">
|
||||
<div className="bg-white rounded-2xl overflow-hidden shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 flex flex-col">
|
||||
<div className="h-64 overflow-hidden">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1563729784474-d77dbb933a9e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
|
||||
alt="SweetCraving Desszertműhely"
|
||||
className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
<div className="h-48 sm:h-64 overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1563729784474-d77dbb933a9e?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="SweetCraving" className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" />
|
||||
</div>
|
||||
<div className="p-8 flex flex-col flex-grow">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">SweetCraving Desszertműhely</h3>
|
||||
<p className="text-sm text-gray-500 font-medium mb-4">Kézműves desszertek – Landing Page csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed">
|
||||
A SweetCraving számára egy fiatalos, barátságos hangulatú bemutatkozó oldalt hoztunk létre.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<span className="text-sm text-gray-500 mr-2">Színek:</span>
|
||||
<div className="w-6 h-6 rounded-full bg-pink-300 border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-yellow-200 border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-white border border-gray-200"></div>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<Link to="/demos/sweetcraving">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300 hover:border-gray-400 hover:bg-gray-50">
|
||||
Oldal megtekintése
|
||||
<ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="p-6 md:p-8 flex flex-col flex-grow">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">SweetCraving</h3>
|
||||
<p className="text-xs text-gray-500 font-medium mb-4 uppercase tracking-wider">Landing Page csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed text-sm md:text-base">Fiatalos, barátságos hangulatú bemutatkozó oldalt hoztunk létre.</p>
|
||||
<Link to="/demos/sweetcraving">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300">
|
||||
Oldal megtekintése <ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card 2: BlueWave */}
|
||||
<div className="bg-white rounded-2xl overflow-hidden shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 flex flex-col">
|
||||
<div className="h-64 overflow-hidden">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1509391366360-2e959784a276?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
|
||||
alt="BlueWave Solar Kft."
|
||||
className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
<div className="h-48 sm:h-64 overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1509391366360-2e959784a276?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="BlueWave" className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" />
|
||||
</div>
|
||||
<div className="p-8 flex flex-col flex-grow">
|
||||
<div className="p-6 md:p-8 flex flex-col flex-grow">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">BlueWave Solar Kft.</h3>
|
||||
<p className="text-sm text-gray-500 font-medium mb-4">Zöld energia megoldások – Pro Web csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed">
|
||||
A BlueWave Solar számára modern, üzleti stílusú, reszponzív weboldalt készítettünk.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<span className="text-sm text-gray-500 mr-2">Színek:</span>
|
||||
<div className="w-6 h-6 rounded-full bg-sky-600 border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-green-500 border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-white border border-gray-200"></div>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<Link to="/demos/bluewave">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300 hover:border-gray-400 hover:bg-gray-50">
|
||||
Oldal megtekintése
|
||||
<ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<p className="text-xs text-gray-500 font-medium mb-4 uppercase tracking-wider">Pro Web csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed text-sm md:text-base">Modern, üzleti stílusú, reszponzív weboldal kalkulátorral.</p>
|
||||
<Link to="/demos/bluewave">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300">
|
||||
Oldal megtekintése <ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Card 3: Steelguard */}
|
||||
<div className="bg-white rounded-2xl overflow-hidden shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 flex flex-col">
|
||||
<div className="h-64 overflow-hidden">
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1518770660439-4636190af475?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
|
||||
alt="Steelguard Biztonságtechnika"
|
||||
className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500"
|
||||
/>
|
||||
<div className="bg-white rounded-2xl overflow-hidden shadow-lg border border-gray-100 hover:shadow-xl transition-all duration-300 flex flex-col md:col-span-2 lg:col-span-1">
|
||||
<div className="h-48 sm:h-64 overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1518770660439-4636190af475?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80" alt="Steelguard" className="w-full h-full object-cover transform hover:scale-105 transition-transform duration-500" />
|
||||
</div>
|
||||
<div className="p-8 flex flex-col flex-grow">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">Steelguard Biztonságtechnika</h3>
|
||||
<p className="text-sm text-gray-500 font-medium mb-4">Biztonságtechnika és IT rendszerek – Enterprise csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed">
|
||||
A Steelguard számára technológiai, sötét tónusú weboldalt készítettünk.
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-3 mb-8">
|
||||
<span className="text-sm text-gray-500 mr-2">Színek:</span>
|
||||
<div className="w-6 h-6 rounded-full bg-black border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-blue-600 border border-gray-200"></div>
|
||||
<div className="w-6 h-6 rounded-full bg-gray-300 border border-gray-200"></div>
|
||||
</div>
|
||||
|
||||
<div className="w-full">
|
||||
<Link to="/demos/steelguard">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300 hover:border-gray-400 hover:bg-gray-50">
|
||||
Oldal megtekintése
|
||||
<ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="p-6 md:p-8 flex flex-col flex-grow">
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">Steelguard</h3>
|
||||
<p className="text-xs text-gray-500 font-medium mb-4 uppercase tracking-wider">Enterprise csomag</p>
|
||||
<p className="text-gray-600 mb-6 flex-grow leading-relaxed text-sm md:text-base">Technológiai, sötét tónusú enterprise weboldal.</p>
|
||||
<Link to="/demos/steelguard">
|
||||
<Button variant="outline" fullWidth className="group justify-between text-gray-700 border-gray-300">
|
||||
Oldal megtekintése <ExternalLink className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -246,58 +202,98 @@ export const Home: React.FC = () => {
|
||||
</section>
|
||||
|
||||
{/* Products/Packages Section */}
|
||||
<section id="products" className="py-24 bg-gray-50 scroll-mt-20">
|
||||
<section id="products" className="py-20 md:py-24 bg-gray-50 scroll-mt-20">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">Csomagajánlataink</h2>
|
||||
<p className="text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
Átlátható árazás, rejtett költségek nélkül. Válassza az Ön céljaihoz leginkább illeszkedő csomagot.
|
||||
<div className="text-center mb-12 md:mb-16">
|
||||
<h2 className="text-2xl md:text-4xl font-bold text-gray-900 mb-4">Csomagajánlataink</h2>
|
||||
<p className="text-lg md:text-xl text-gray-600 max-w-2xl mx-auto">
|
||||
Átlátható árazás, rejtett költségek nélkül.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{packages.map((pkg, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`relative bg-white rounded-2xl shadow-xl flex flex-col p-8 transition-transform hover:-translate-y-2 duration-300 ${pkg.isPopular ? 'border-2 border-primary ring-4 ring-purple-100' : 'border border-gray-100'}`}
|
||||
>
|
||||
{pkg.isPopular && (
|
||||
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-gradient-to-r from-primary to-secondary text-white px-4 py-1 rounded-full text-sm font-bold shadow-lg flex items-center gap-1">
|
||||
<Star className="w-4 h-4 fill-current" /> Legnépszerűbb
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8">
|
||||
{packages.map((pkg, index) => {
|
||||
const remaining = (pkg.total_price || 0) - (pkg.advance_price || 0);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={`relative bg-white rounded-2xl shadow-xl flex flex-col p-6 md:p-8 transition-transform hover:-translate-y-2 duration-300 ${pkg.isPopular ? 'border-2 border-primary ring-4 ring-purple-100' : 'border border-gray-100'}`}
|
||||
>
|
||||
{pkg.isPopular && (
|
||||
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-gradient-to-r from-primary to-secondary text-white px-4 py-1 rounded-full text-xs md:text-sm font-bold shadow-lg flex items-center gap-1">
|
||||
<Star className="w-3 h-3 md:w-4 h-4 fill-current" /> Legnépszerűbb
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="text-xl md:text-2xl font-bold text-gray-900">{pkg.name}</h3>
|
||||
<p className="text-gray-500 mt-2 text-xs md:text-sm min-h-[40px]">{pkg.desc}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="text-2xl font-bold text-gray-900">{pkg.name}</h3>
|
||||
<p className="text-gray-500 mt-2 text-sm min-h-[40px]">{pkg.desc}</p>
|
||||
<div className="mb-8">
|
||||
<span className="text-2xl md:text-3xl font-extrabold text-gray-900 block">
|
||||
{pkg.is_custom_price ? 'Egyedi árazás' : (pkg.price || 'Egyedi árazás')}
|
||||
</span>
|
||||
{!pkg.is_custom_price && pkg.advance_price && pkg.advance_price > 0 ? (
|
||||
<div className="mt-3 space-y-1 border-t border-gray-100 pt-3">
|
||||
<div className="flex items-center text-[10px] md:text-xs font-bold text-gray-400 uppercase tracking-tight">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-blue-400 mr-2"></div>
|
||||
<span>Előleg: {formatPrice(pkg.advance_price)}</span>
|
||||
</div>
|
||||
<div className="flex items-center text-[10px] md:text-xs font-bold text-gray-400 uppercase tracking-tight">
|
||||
<div className="w-1.5 h-1.5 rounded-full bg-primary mr-2"></div>
|
||||
<span>Fennmaradó: {formatPrice(remaining)} (demó elfogadása után)</span>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<ul className="space-y-3 md:space-y-4 mb-8 flex-grow">
|
||||
{pkg.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-start text-gray-600">
|
||||
<Check className="w-4 h-4 md:w-5 h-5 text-green-500 mr-2 md:mr-3 flex-shrink-0 mt-0.5" />
|
||||
<span className="text-xs md:text-sm">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto">
|
||||
<Link to="/#rendeles" className="w-full">
|
||||
<Button
|
||||
variant={pkg.isPopular ? 'primary' : 'outline'}
|
||||
fullWidth
|
||||
>
|
||||
{pkg.cta}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mb-8">
|
||||
<span className="text-3xl font-extrabold text-gray-900">{pkg.price}</span>
|
||||
{pkg.price.includes('Ft') && <span className="text-gray-500 text-sm font-normal"> + ÁFA</span>}
|
||||
</div>
|
||||
|
||||
<ul className="space-y-4 mb-8 flex-grow">
|
||||
{pkg.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-start text-gray-600">
|
||||
<Check className="w-5 h-5 text-green-500 mr-3 flex-shrink-0 mt-0.5" />
|
||||
<span className="text-sm">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto">
|
||||
<Link to="/#rendeles">
|
||||
<Button
|
||||
variant={pkg.isPopular ? 'primary' : 'outline'}
|
||||
fullWidth
|
||||
>
|
||||
{pkg.cta}
|
||||
</Button>
|
||||
</Link>
|
||||
{/* Maintenance Info Panel */}
|
||||
<div className="mt-12 w-full animate-fade-in">
|
||||
<div className="bg-gradient-to-br from-white to-gray-50 border border-gray-200 rounded-[32px] p-6 md:p-10 shadow-sm flex flex-col md:flex-row items-center gap-6 md:gap-10">
|
||||
<div className="w-16 h-16 md:w-20 md:h-20 bg-primary/10 rounded-3xl flex items-center justify-center text-primary shrink-0 shadow-inner">
|
||||
<ShieldCheck className="w-8 h-8 md:w-10 md:h-10" />
|
||||
</div>
|
||||
<div className="flex-grow text-center md:text-left">
|
||||
<h4 className="text-lg md:text-xl font-black text-gray-900 mb-2 uppercase tracking-tighter">Éves üzemeltetés és karbantartás</h4>
|
||||
<p className="text-sm md:text-base text-gray-600 leading-relaxed mb-4">
|
||||
A weboldal stabil működéséhez, a tárhely biztosításához és a folyamatos biztonsági frissítésekhez éves díjat alkalmazunk. <strong>A rendelés ára tartalmazza az első év üzemeltetését, így az éves díj megfizetése csak az átadást követő egy év múlva válik először esedékessé.</strong>
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center md:justify-start gap-4 text-[10px] md:text-xs font-bold uppercase tracking-widest text-gray-400">
|
||||
<span className="flex items-center gap-1.5"><Clock className="w-3.5 h-3.5 text-primary" /> 2026-ig garantált ár</span>
|
||||
<span className="flex items-center gap-1.5"><Info className="w-3.5 h-3.5 text-primary" /> Évente inflációkövető módosítás lehetséges</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="bg-white border-2 border-primary/20 rounded-[24px] px-8 py-6 text-center shadow-lg shadow-primary/5 min-w-[200px]">
|
||||
<p className="text-[10px] font-black text-gray-400 uppercase tracking-[0.2em] mb-1">Díj / Év</p>
|
||||
<p className="text-2xl md:text-3xl font-black text-primary">59 990 Ft</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -306,7 +302,7 @@ export const Home: React.FC = () => {
|
||||
<ProcessSection />
|
||||
|
||||
{/* Order Form Section */}
|
||||
<section id="rendeles" className="py-20 bg-white scroll-mt-20">
|
||||
<section id="rendeles" className="py-16 md:py-20 bg-white scroll-mt-20">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<OrderForm />
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { ArrowLeft, Shield, Mail, Globe, Database, Cookie, UserCheck, Scale, Lock } from 'lucide-react';
|
||||
@@ -84,7 +85,7 @@ export const Privacy: React.FC = () => {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 2 */}
|
||||
{/* Section 2 - UPDATED */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-3">
|
||||
<span className="flex items-center justify-center w-8 h-8 rounded-lg bg-secondary/10 text-secondary text-sm">2</span>
|
||||
@@ -94,11 +95,10 @@ export const Privacy: React.FC = () => {
|
||||
<p>Az adatkezelés a GDPR 6. cikk (1) bekezdése alapján történik, az alábbi jogalapokon:</p>
|
||||
<ul className="grid grid-cols-1 md:grid-cols-2 gap-3">
|
||||
{[
|
||||
'szerződés teljesítése, valamint',
|
||||
'szerződés megkötését megelőző lépések,',
|
||||
'szerződés teljesítése, valamint szerződés megkötését megelőző lépések,',
|
||||
'jogi kötelezettség teljesítése (számlázás),',
|
||||
'jogos érdek (a szolgáltatás működtetése és biztonsága),',
|
||||
'érintetti hozzájárulás (cookie-k alkalmazása).'
|
||||
'érintetti hozzájárulás (marketing célú hírlevélre való feliratkozás és cookie-k alkalmazása).'
|
||||
].map((item, i) => (
|
||||
<li key={i} className="flex items-center gap-3 text-sm bg-gray-50 p-3 rounded-lg border border-gray-100">
|
||||
<UserCheck className="w-4 h-4 text-secondary flex-shrink-0" />
|
||||
@@ -106,10 +106,14 @@ export const Privacy: React.FC = () => {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<p className="bg-blue-50 p-4 rounded-xl border border-blue-100 text-gray-700 mt-4">
|
||||
A MotionWeb szolgáltatásai fix csomagárakon érhetők el. A megrendelés leadásával és az előleg megfizetésével a felek között szerződés jön létre.
|
||||
</p>
|
||||
<p className="font-bold text-gray-800">A MotionWeb nem végez marketing célú adatkezelést.</p>
|
||||
<div className="mt-6 space-y-3">
|
||||
<p className="bg-blue-50 p-4 rounded-xl border border-blue-100 text-gray-700">
|
||||
A MotionWeb szolgáltatásai fix csomagárakon érhetők el. A megrendelés leadásával és az előleg megfizetésével a felek között szerződés jön létre.
|
||||
</p>
|
||||
<p className="text-gray-700">
|
||||
A hírlevélre való feliratkozás önkéntes, az erre vonatkozó hozzájárulás bármikor korlátozás és indokolás nélkül, ingyenesen visszavonható.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Check, Star } from 'lucide-react';
|
||||
import { Check, Star, ShieldCheck, Clock, Info } from 'lucide-react';
|
||||
import { Button } from '../components/Button';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { supabase } from '../lib/supabaseClient';
|
||||
@@ -14,11 +15,22 @@ export const Products: React.FC = () => {
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('plans')
|
||||
.select('*')
|
||||
.order('price', { ascending: true });
|
||||
.select('*');
|
||||
|
||||
if (!error && data && data.length > 0) {
|
||||
setPackages(data);
|
||||
const sortedData = [...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;
|
||||
});
|
||||
setPackages(sortedData);
|
||||
} else {
|
||||
const sortedDefaults = [...defaultPlans].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;
|
||||
});
|
||||
setPackages(sortedDefaults);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error fetching plans:", e);
|
||||
@@ -27,6 +39,8 @@ export const Products: React.FC = () => {
|
||||
fetchPlans();
|
||||
}, []);
|
||||
|
||||
const formatPrice = (num: number) => num.toLocaleString('hu-HU') + ' Ft';
|
||||
|
||||
return (
|
||||
<div className="pt-20 bg-gray-50 min-h-screen">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
|
||||
@@ -38,48 +52,88 @@ export const Products: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{packages.map((pkg, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`relative bg-white rounded-2xl shadow-xl flex flex-col p-8 transition-transform hover:-translate-y-2 duration-300 ${pkg.isPopular ? 'border-2 border-primary ring-4 ring-purple-100' : 'border border-gray-100'}`}
|
||||
>
|
||||
{pkg.isPopular && (
|
||||
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-gradient-to-r from-primary to-secondary text-white px-4 py-1 rounded-full text-sm font-bold shadow-lg flex items-center gap-1">
|
||||
<Star className="w-4 h-4 fill-current" /> Legnépszerűbb
|
||||
{packages.map((pkg, index) => {
|
||||
const remaining = (pkg.total_price || 0) - (pkg.advance_price || 0);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={`relative bg-white rounded-2xl shadow-xl flex flex-col p-8 transition-transform hover:-translate-y-2 duration-300 ${pkg.isPopular ? 'border-2 border-primary ring-4 ring-purple-100' : 'border border-gray-100'}`}
|
||||
>
|
||||
{pkg.isPopular && (
|
||||
<div className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-gradient-to-r from-primary to-secondary text-white px-4 py-1 rounded-full text-sm font-bold shadow-lg flex items-center gap-1">
|
||||
<Star className="w-4 h-4 fill-current" /> Legnépszerűbb
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="text-2xl font-bold text-gray-900">{pkg.name}</h3>
|
||||
<p className="text-gray-500 mt-2 text-sm min-h-[40px]">{pkg.desc}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-6">
|
||||
<h3 className="text-2xl font-bold text-gray-900">{pkg.name}</h3>
|
||||
<p className="text-gray-500 mt-2 text-sm min-h-[40px]">{pkg.desc}</p>
|
||||
<div className="mb-8">
|
||||
<span className="text-3xl font-extrabold text-gray-900 block">
|
||||
{pkg.is_custom_price ? 'Egyedi árazás' : (pkg.price || 'Egyedi árazás')}
|
||||
</span>
|
||||
{!pkg.is_custom_price && pkg.advance_price && pkg.advance_price > 0 ? (
|
||||
<div className="mt-3 p-3 bg-gray-50 rounded-xl border border-gray-100">
|
||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-1 text-center border-b border-gray-200 pb-1">Fizetési ütemezés</p>
|
||||
<div className="mt-2 space-y-1">
|
||||
<p className="text-sm font-bold text-gray-700 flex justify-between"><span>Előleg:</span> <span>{formatPrice(pkg.advance_price)}</span></p>
|
||||
<p className="text-sm font-medium text-gray-500 flex flex-col pt-1 border-t border-gray-100 mt-1">
|
||||
<span className="text-[10px] font-bold text-primary uppercase">Demó elfogadása után:</span>
|
||||
<span className="font-bold text-gray-700">{formatPrice(remaining)}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<ul className="space-y-4 mb-8 flex-grow">
|
||||
{pkg.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-start text-gray-600">
|
||||
<Check className="w-5 h-5 text-green-500 mr-3 flex-shrink-0 mt-0.5" />
|
||||
<span className="text-sm">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto">
|
||||
<Link to="/contact">
|
||||
<Button
|
||||
variant={pkg.isPopular ? 'primary' : 'outline'}
|
||||
fullWidth
|
||||
>
|
||||
{pkg.cta}
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="mb-8">
|
||||
<span className="text-3xl font-extrabold text-gray-900">{pkg.price}</span>
|
||||
{pkg.price.includes('Ft') && <span className="text-gray-500 text-sm font-normal"> + ÁFA</span>}
|
||||
</div>
|
||||
|
||||
<ul className="space-y-4 mb-8 flex-grow">
|
||||
{pkg.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-start text-gray-600">
|
||||
<Check className="w-5 h-5 text-green-500 mr-3 flex-shrink-0 mt-0.5" />
|
||||
<span className="text-sm">{feature}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="mt-auto">
|
||||
<Link to="/contact">
|
||||
<Button
|
||||
variant={pkg.isPopular ? 'primary' : 'outline'}
|
||||
fullWidth
|
||||
>
|
||||
{pkg.cta}
|
||||
</Button>
|
||||
</Link>
|
||||
{/* Maintenance Info Panel */}
|
||||
<div className="mt-12 w-full">
|
||||
<div className="bg-white border border-gray-200 rounded-[32px] p-6 md:p-10 shadow-sm flex flex-col md:flex-row items-center gap-6 md:gap-10">
|
||||
<div className="w-16 h-16 md:w-20 md:h-20 bg-primary/5 rounded-3xl flex items-center justify-center text-primary shrink-0 border border-primary/10">
|
||||
<ShieldCheck className="w-8 h-8 md:w-10 md:h-10" />
|
||||
</div>
|
||||
<div className="flex-grow text-center md:text-left">
|
||||
<h4 className="text-lg md:text-xl font-bold text-gray-900 mb-2 uppercase tracking-tight">Éves üzemeltetés és karbantartás</h4>
|
||||
<p className="text-sm md:text-base text-gray-600 leading-relaxed mb-4">
|
||||
Minden csomagunkhoz egységes, kedvező üzemeltetési díj tartozik, amely tartalmazza a tárhelyet, a biztonsági mentéseket és a folyamatos monitorozást. <strong>A csomagár tartalmazza az első év üzemeltetését, így az első éves díj megfizetése csak a projekt átadását követő egy év múlva válik esedékessé.</strong>
|
||||
</p>
|
||||
<div className="flex flex-wrap justify-center md:justify-start gap-4 text-[10px] md:text-xs font-bold uppercase tracking-widest text-gray-400">
|
||||
<span className="flex items-center gap-1.5"><Clock className="w-3.5 h-3.5 text-primary" /> 2026-ig rögzített ár</span>
|
||||
<span className="flex items-center gap-1.5"><Info className="w-3.5 h-3.5 text-primary" /> Éves inflációkövető korrekció lehetséges</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="bg-primary text-white rounded-[24px] px-8 py-6 text-center shadow-xl shadow-primary/20 min-w-[220px]">
|
||||
<p className="text-[10px] font-bold opacity-70 uppercase tracking-[0.2em] mb-1">Éves Fenntartás</p>
|
||||
<p className="text-2xl md:text-3xl font-black">59 990 Ft</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-20 bg-white rounded-2xl p-8 md:p-12 shadow-sm border border-gray-100 flex flex-col md:flex-row items-center justify-between gap-8">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
// Add XCircle to the import list
|
||||
import { ArrowLeft, FileText, Globe, Mail, Shield, XCircle } from 'lucide-react';
|
||||
import { ArrowLeft, FileText, Globe, Mail, Shield, XCircle, BellRing, Settings2 } from 'lucide-react';
|
||||
import { Button } from '../components/Button';
|
||||
|
||||
export const Terms: React.FC = () => {
|
||||
@@ -207,19 +207,27 @@ export const Terms: React.FC = () => {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 10 */}
|
||||
{/* Section 10 - UPDATED */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-3">
|
||||
<span className="flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary text-sm">10</span>
|
||||
Admin felület és utólagos módosítások
|
||||
Fenntartás és technikai szolgáltatások
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<p>Az admin felület kizárólag azokat a funkciókat tartalmazza, amelyek a megrendelés során előzetesen egyeztetésre kerültek.</p>
|
||||
<p>A megrendelő kizárólag az admin felületen elérhető funkciók körében jogosult önálló módosításokra.</p>
|
||||
<p>Egyszerű, technikailag nem összetett kérések (például szövegcsere) esetén a megrendelő e-mailben jelezheti igényét, amelynek teljesítésében a MotionWeb eseti alapon segítséget nyújthat.</p>
|
||||
<p className="font-bold text-gray-800 border-t border-gray-100 pt-4">Dizájnmódosítás, új funkció, új aloldal vagy admin bővítés külön megrendelésnek minősül.</p>
|
||||
<p>A külön megrendelések egyedi árazás alapján, előzetes befizetést követően valósulnak meg.</p>
|
||||
<p className="italic">A MotionWeb nem nyújt folyamatos technikai támogatási vagy karbantartási szolgáltatást.</p>
|
||||
<p>A weboldalak üzemeltetése éves fenntartási díjhoz kötött, amely tartalmazza a tárhelyszolgáltatást, az SSL tanúsítványt, a domain/DNS kezelést és az alapvető biztonsági frissítéseket.</p>
|
||||
<div className="bg-purple-50 p-6 rounded-2xl border border-purple-100 flex items-start gap-4">
|
||||
<div className="p-2 bg-white rounded-lg shadow-sm">
|
||||
<Settings2 className="w-5 h-5 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm text-gray-700">
|
||||
A fenntartási díj aktuális mértékét a weboldalon közzétett díjszabás tartalmazza. A fenntartási díj meg nem fizetése a szolgáltatás (weboldal elérhetősége) felfüggesztését vonhatja maga után.
|
||||
</p>
|
||||
<p className="text-sm text-primary font-bold mt-2">
|
||||
A fenntartási díj nem tartalmazza az új funkciók fejlesztését vagy a dizájnmódosításokat.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -300,6 +308,25 @@ export const Terms: React.FC = () => {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Section 17 - NEW */}
|
||||
<section>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-4 flex items-center gap-3">
|
||||
<span className="flex items-center justify-center w-8 h-8 rounded-lg bg-primary/10 text-primary text-sm">17</span>
|
||||
Kommunikáció és marketing
|
||||
</h3>
|
||||
<div className="space-y-4">
|
||||
<p>A szolgáltató jogosult a megrendelő által megadott e-mail címre a szolgáltatással kapcsolatos technikai és tranzakciós üzeneteket küldeni.</p>
|
||||
<div className="bg-blue-50 p-6 rounded-2xl border border-blue-100 flex items-start gap-4">
|
||||
<div className="p-2 bg-white rounded-lg shadow-sm">
|
||||
<BellRing className="w-5 h-5 text-blue-500" />
|
||||
</div>
|
||||
<p className="text-sm text-gray-700">
|
||||
Amennyiben a felhasználó a weboldalon ehhez kifejezetten hozzájárult, a szolgáltató jogosult marketing célú hírleveleket küldeni. A hírlevélről a felhasználó bármikor ingyenesen leiratkozhat az e-mailek alján található linken vagy a szolgáltató kapcsolattartási e-mail címén.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -140,7 +140,8 @@ export const Login: React.FC = () => {
|
||||
<div>
|
||||
<div className="flex justify-between items-center mb-1">
|
||||
<label htmlFor="password" className="block text-xs font-black text-gray-400 uppercase tracking-widest">Jelszó</label>
|
||||
<Link to="/auth/forgot-password" size="sm" className="text-[10px] font-black text-primary hover:underline uppercase tracking-widest">Elfelejtette?</Link>
|
||||
{/* Fixed: removed invalid 'size' prop from Link component */}
|
||||
<Link to="/auth/forgot-password" className="text-[10px] font-black text-primary hover:underline uppercase tracking-widest">Elfelejtette?</Link>
|
||||
</div>
|
||||
<input id="password" type="password" required value={password} onChange={(e) => setPassword(e.target.value)} className="appearance-none block w-full px-4 py-3 border border-gray-200 rounded-xl shadow-sm focus:outline-none focus:ring-4 focus:ring-primary/10 focus:border-primary sm:text-sm bg-white text-gray-900 font-medium" placeholder="••••••••" />
|
||||
</div>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { ArrowLeft, Sun, Battery, Zap, ChevronRight, Menu, X, Phone, Mail, CheckCircle, Home, Info, Briefcase, Calculator, ArrowRight } from 'lucide-react';
|
||||
import {
|
||||
ArrowLeft, ArrowRight, Sun, Battery, Zap, ChevronRight, Menu, X, Phone,
|
||||
Mail, CheckCircle, Home, Info, Briefcase, Calculator,
|
||||
MapPin, Clock, Star, Share2, ArrowUpRight, Play, BookOpen
|
||||
} from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const BlueWave: React.FC = () => {
|
||||
const [activePage, setActivePage] = useState<'home' | 'services' | 'about' | 'contact'>('home');
|
||||
const [activePage, setActivePage] = useState<'home' | 'services' | 'blog' | 'about' | 'contact'>('home');
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
// Smooth scroll to top when "changing pages" in this SPA simulation
|
||||
useEffect(() => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}, [activePage]);
|
||||
|
||||
// Navbar scroll effect
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setScrolled(window.scrollY > 20);
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
@@ -22,267 +24,224 @@ export const BlueWave: React.FC = () => {
|
||||
const navItems = [
|
||||
{ id: 'home', label: 'Főoldal', icon: Home },
|
||||
{ id: 'services', label: 'Megoldások', icon: Zap },
|
||||
{ id: 'about', label: 'Cégünkről', icon: Info },
|
||||
{ id: 'blog', label: 'Blog', icon: BookOpen },
|
||||
{ id: 'about', label: 'Rólunk', icon: Info },
|
||||
{ id: 'contact', label: 'Kapcsolat', icon: Phone },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="font-sans text-gray-800 bg-white min-h-screen flex flex-col selection:bg-[#0284c7] selection:text-white">
|
||||
{/* Return to Main Site */}
|
||||
<div className="fixed bottom-6 right-6 z-[60]">
|
||||
{/* Back to main site button */}
|
||||
<div className="fixed bottom-4 right-4 md:bottom-6 md:right-6 z-[60]">
|
||||
<Link to="/#references">
|
||||
<button className="bg-gray-900 text-white shadow-xl px-5 py-3 rounded-xl text-sm font-sans font-medium flex items-center hover:bg-gray-800 hover:-translate-y-1 transition-all duration-300">
|
||||
<ArrowLeft className="w-4 h-4 mr-2" /> Vissza a referenciákhoz
|
||||
<button className="bg-gray-900 text-white shadow-2xl px-4 md:px-5 py-2.5 md:py-3 rounded-lg md:rounded-xl text-xs md:text-sm font-sans font-bold flex items-center hover:bg-[#0284c7] transition-all transform hover:-translate-y-1">
|
||||
<ArrowLeft className="w-4 h-4 mr-2" /> Vissza a portfólióhoz
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Top Bar */}
|
||||
<div className="bg-[#0f172a] text-gray-300 py-2.5 px-4 text-xs font-medium hidden md:block border-b border-gray-800">
|
||||
<div className="bg-[#0f172a] text-gray-300 py-2.5 px-4 text-[10px] md:text-xs font-semibold hidden sm:block border-b border-gray-800">
|
||||
<div className="max-w-7xl mx-auto flex justify-between items-center">
|
||||
<div className="flex space-x-8">
|
||||
<div className="flex space-x-6">
|
||||
<span className="flex items-center hover:text-white transition-colors cursor-pointer"><Phone className="w-3.5 h-3.5 mr-2 text-[#38bdf8]" /> +36 30 999 8888</span>
|
||||
<span className="flex items-center hover:text-white transition-colors cursor-pointer"><Mail className="w-3.5 h-3.5 mr-2 text-[#38bdf8]" /> info@bluewave-solar.demo</span>
|
||||
<span className="flex items-center hover:text-white transition-colors cursor-pointer"><Mail className="w-3.5 h-3.5 mr-2 text-[#38bdf8]" /> info@bluewave-solar.hu</span>
|
||||
</div>
|
||||
<div className="flex space-x-6">
|
||||
<a href="#" className="hover:text-white transition-colors">Lakossági</a>
|
||||
<a href="#" className="hover:text-white transition-colors">Ipari</a>
|
||||
<a href="#" className="hover:text-white transition-colors text-[#38bdf8]">Partnerprogram</a>
|
||||
<span className="text-[#38bdf8] uppercase tracking-widest text-[9px]">Ingyenes felmérés az ország egész területén</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navbar */}
|
||||
<nav className={`sticky top-0 z-50 transition-all duration-300 border-b ${scrolled ? 'bg-white/95 backdrop-blur-md shadow-md py-0 border-gray-200' : 'bg-white py-4 border-transparent'}`}>
|
||||
<nav className={`sticky top-0 z-50 transition-all duration-500 border-b ${scrolled ? 'bg-white/95 backdrop-blur-md shadow-xl py-0 border-gray-100' : 'bg-white py-2 md:py-4 border-transparent'}`}>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between h-20 items-center">
|
||||
<div className="flex justify-between h-16 md:h-20 items-center">
|
||||
<div className="flex items-center cursor-pointer group" onClick={() => setActivePage('home')}>
|
||||
<div className="bg-gradient-to-tr from-[#0284c7] to-[#0ea5e9] p-2.5 rounded-xl mr-3 shadow-lg shadow-sky-200 group-hover:scale-105 transition-transform duration-300">
|
||||
<Sun className="w-7 h-7 text-white" />
|
||||
<div className="bg-gradient-to-tr from-[#0284c7] to-[#0ea5e9] p-2.5 rounded-xl mr-3 shadow-lg shadow-sky-100 group-hover:rotate-12 transition-transform">
|
||||
<Sun className="w-6 h-6 md:w-8 md:h-8 text-white" />
|
||||
</div>
|
||||
<div className="leading-none">
|
||||
<span className="block text-2xl font-bold text-gray-900 tracking-tight">BlueWave</span>
|
||||
<span className="block text-xs font-bold text-[#0284c7] uppercase tracking-widest ml-0.5">Solar Systems</span>
|
||||
<span className="block text-xl md:text-2xl font-black text-gray-900 tracking-tighter uppercase">BlueWave</span>
|
||||
<span className="block text-[8px] md:text-[10px] font-black text-[#0284c7] uppercase tracking-[0.3em] ml-0.5">Napenergia Stúdió</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden md:flex items-center space-x-1">
|
||||
<div className="hidden lg:flex items-center space-x-2">
|
||||
{navItems.map((item) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => setActivePage(item.id as any)}
|
||||
className={`relative px-5 py-2.5 rounded-lg text-sm font-semibold transition-all duration-300 ${
|
||||
className={`px-4 py-2 rounded-xl text-sm font-bold transition-all ${
|
||||
activePage === item.id
|
||||
? 'text-[#0284c7] bg-sky-50'
|
||||
: 'text-gray-600 hover:text-[#0284c7] hover:bg-gray-50'
|
||||
: 'text-gray-500 hover:text-[#0284c7] hover:bg-gray-50'
|
||||
}`}
|
||||
>
|
||||
{item.label}
|
||||
{activePage === item.id && (
|
||||
<span className="absolute bottom-0 left-1/2 transform -translate-x-1/2 w-1/2 h-0.5 bg-[#0284c7] rounded-full"></span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
<div className="pl-4 ml-4 border-l border-gray-200">
|
||||
<div className="pl-6 ml-4 border-l border-gray-100">
|
||||
<button
|
||||
onClick={() => setActivePage('contact')}
|
||||
className="bg-[#0284c7] hover:bg-[#0369a1] text-white px-6 py-3 rounded-lg font-bold text-sm transition-all shadow-lg shadow-sky-200 hover:-translate-y-0.5"
|
||||
className="bg-[#0284c7] hover:bg-gray-900 text-white px-6 py-3 rounded-xl font-black text-xs uppercase tracking-widest transition-all shadow-lg shadow-sky-100 active:scale-95"
|
||||
>
|
||||
Ingyenes felmérés
|
||||
Ajánlatkérés
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-6 md:hidden">
|
||||
<button onClick={() => setMobileMenuOpen(!mobileMenuOpen)} className="p-2 text-gray-600 hover:bg-gray-100 rounded-lg">
|
||||
<button onClick={() => setMobileMenuOpen(!mobileMenuOpen)} className="lg:hidden p-2 text-gray-600 bg-gray-50 rounded-lg">
|
||||
{mobileMenuOpen ? <X /> : <Menu />}
|
||||
</button>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="md:hidden bg-white border-t border-gray-100 p-4 space-y-2 shadow-xl absolute w-full animate-fade-in">
|
||||
<div className="lg:hidden bg-white border-t border-gray-100 p-6 space-y-3 shadow-2xl absolute w-full animate-fade-in">
|
||||
{navItems.map((item) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => { setActivePage(item.id as any); setMobileMenuOpen(false); }}
|
||||
className={`w-full flex items-center px-4 py-4 rounded-xl text-base font-medium ${activePage === item.id ? 'bg-sky-50 text-[#0284c7]' : 'text-gray-700 hover:bg-gray-50'}`}
|
||||
className={`w-full flex items-center px-5 py-4 rounded-2xl text-base font-bold ${activePage === item.id ? 'bg-sky-50 text-[#0284c7]' : 'text-gray-600'}`}
|
||||
>
|
||||
<item.icon className="w-5 h-5 mr-3 opacity-70" />
|
||||
<item.icon className="w-5 h-5 mr-4 opacity-50" />
|
||||
{item.label}
|
||||
</button>
|
||||
))}
|
||||
<button
|
||||
onClick={() => { setActivePage('contact'); setMobileMenuOpen(false); }}
|
||||
className="w-full mt-4 bg-[#0284c7] text-white px-4 py-4 rounded-xl font-bold shadow-md"
|
||||
className="w-full mt-6 bg-gray-900 text-white py-5 rounded-2xl font-black uppercase tracking-widest text-xs"
|
||||
>
|
||||
Ingyenes felmérés
|
||||
Ingyenes Konzultáció
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
|
||||
{/* Main Content Area - Simulating Routing with smooth fade */}
|
||||
<main className="flex-grow relative">
|
||||
{/* Main Content Area */}
|
||||
<main className="flex-grow">
|
||||
<div key={activePage} className="animate-fade-in">
|
||||
|
||||
{/* HOME PAGE */}
|
||||
{/* --- HOME PAGE --- */}
|
||||
{activePage === 'home' && (
|
||||
<>
|
||||
<section className="relative bg-[#0f172a] py-32 lg:py-48 overflow-hidden">
|
||||
<div className="absolute inset-0 z-0">
|
||||
<img src="https://images.unsplash.com/photo-1509391366360-2e959784a276?ixlib=rb-4.0.3&auto=format&fit=crop&w=2000&q=80" alt="Solar Panels" className="w-full h-full object-cover opacity-30 scale-105 animate-pulse-slow" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-[#0f172a] via-[#0f172a]/90 to-transparent"></div>
|
||||
{/* Hero */}
|
||||
<section className="relative min-h-[85vh] flex items-center pt-20 overflow-hidden px-4">
|
||||
<div className="absolute inset-0 z-0 scale-105">
|
||||
<img src="https://images.unsplash.com/photo-1508514177221-188b1cf16e9d?ixlib=rb-4.0.3&auto=format&fit=crop&w=2000&q=80" alt="Home Solar" className="w-full h-full object-cover" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-white via-white/80 to-transparent"></div>
|
||||
</div>
|
||||
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-3xl">
|
||||
<div className="inline-flex items-center px-4 py-2 rounded-full bg-[#0ea5e9]/10 text-[#38bdf8] text-sm font-bold mb-8 border border-[#0ea5e9]/20 backdrop-blur-sm animate-fade-in-up">
|
||||
<CheckCircle className="w-4 h-4 mr-2" /> Hivatalos állami kivitelező partner
|
||||
<div className="relative z-10 max-w-7xl mx-auto w-full">
|
||||
<div className="max-w-2xl">
|
||||
<div className="inline-flex items-center px-4 py-2 rounded-full bg-sky-50 text-[#0284c7] text-[10px] md:text-xs font-black uppercase tracking-widest mb-8 border border-sky-100 shadow-sm animate-fade-in-up">
|
||||
<Star className="w-3 h-3 mr-2 fill-current" /> 2024 Év Kivitelezője Díj
|
||||
</div>
|
||||
<h1 className="text-5xl md:text-7xl font-extrabold text-white mb-8 leading-tight animate-fade-in-up" style={{ animationDelay: '0.1s' }}>
|
||||
Váltson tiszta energiára <br/>
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-[#38bdf8] to-[#0ea5e9]">a jövőjéért</span>
|
||||
<h1 className="text-4xl md:text-7xl font-black text-gray-900 mb-8 leading-[0.9] tracking-tighter animate-fade-in-up" style={{ animationDelay: '0.1s' }}>
|
||||
A NAPENERGIA <br/>
|
||||
<span className="text-[#0284c7]">MINDENKIÉ.</span>
|
||||
</h1>
|
||||
<p className="text-xl text-gray-300 mb-10 leading-relaxed max-w-2xl animate-fade-in-up" style={{ animationDelay: '0.2s' }}>
|
||||
Csökkentse rezsijét akár 100%-kal prémium napelem rendszereinkkel. Teljeskörű ügyintézés a tervezéstől a kulcsrakész átadásig, 25 év garanciával.
|
||||
<p className="text-lg md:text-xl text-gray-600 mb-10 leading-relaxed font-medium animate-fade-in-up" style={{ animationDelay: '0.2s' }}>
|
||||
Felejtse el a villanyszámlát. Komplett napelemes rendszerek telepítése 0% önerővel, teljes körű állami támogatás ügyintézéssel.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-5 animate-fade-in-up" style={{ animationDelay: '0.3s' }}>
|
||||
<button onClick={() => setActivePage('contact')} className="bg-[#0284c7] hover:bg-[#0369a1] text-white px-10 py-4 rounded-xl font-bold text-lg transition-all flex items-center justify-center shadow-lg shadow-sky-900/50 hover:scale-105">
|
||||
Kalkuláció kérése <ChevronRight className="w-5 h-5 ml-2" />
|
||||
<div className="flex flex-col sm:flex-row gap-4 animate-fade-in-up" style={{ animationDelay: '0.3s' }}>
|
||||
<button onClick={() => setActivePage('contact')} className="bg-[#0284c7] hover:bg-gray-900 text-white px-10 py-5 rounded-2xl font-black text-sm uppercase tracking-widest transition-all shadow-xl shadow-sky-200 flex items-center justify-center">
|
||||
Kérjen ajánlatot <ArrowUpRight className="ml-2 w-5 h-5" />
|
||||
</button>
|
||||
<button onClick={() => setActivePage('services')} className="bg-white/5 hover:bg-white/10 text-white backdrop-blur-sm px-10 py-4 rounded-xl font-bold text-lg transition-all border border-white/10 hover:border-white/30">
|
||||
Rendszereink
|
||||
<button onClick={() => setActivePage('services')} className="bg-white hover:bg-gray-50 text-gray-900 border-2 border-gray-100 px-10 py-5 rounded-2xl font-black text-sm uppercase tracking-widest transition-all">
|
||||
Ismerje meg a technológiát
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 flex items-center gap-8 text-gray-400 text-sm font-medium animate-fade-in-up" style={{ animationDelay: '0.5s' }}>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div> 1000+ elégedett ügyfél
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div> Országos lefedettség
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="py-24 bg-gray-50 relative">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 -mt-32 relative z-20">
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ icon: Sun, color: 'text-[#0284c7]', bg: 'bg-sky-50', title: 'Prémium Panelek', desc: 'Tier-1 kategóriás napelemek 25 év teljesítménygaranciával és kiemelkedő hatásfokkal.' },
|
||||
{ icon: Battery, color: 'text-emerald-600', bg: 'bg-emerald-50', title: 'Energiatárolás', desc: 'Hibrid rendszerek és akkumulátoros megoldások a teljes függetlenségért.' },
|
||||
{ icon: Briefcase, color: 'text-orange-600', bg: 'bg-orange-50', title: 'Kulcsrakész', desc: 'Minden papírmunkát, pályázatot és engedélyeztetést elintézünk Ön helyett.' }
|
||||
].map((item, i) => (
|
||||
<div key={i} className="bg-white p-10 rounded-2xl shadow-xl border border-gray-100 hover:-translate-y-2 transition-transform duration-300">
|
||||
<div className={`w-16 h-16 ${item.bg} rounded-2xl flex items-center justify-center mb-8 ${item.color}`}>
|
||||
<item.icon className="w-8 h-8" />
|
||||
</div>
|
||||
<h3 className="text-2xl font-bold mb-4 text-gray-900">{item.title}</h3>
|
||||
<p className="text-gray-600 leading-relaxed">{item.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
{/* Status Grid */}
|
||||
<section className="py-20 bg-white border-b border-gray-100">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12">
|
||||
{[
|
||||
{ val: '1200+', label: 'Telepített rendszer' },
|
||||
{ val: '25 Év', label: 'Garancia' },
|
||||
{ val: '99%', label: 'Ügyfél-elégedettség' },
|
||||
{ val: '24 Óra', label: 'Válaszidő' }
|
||||
].map((s, i) => (
|
||||
<div key={i} className="text-center">
|
||||
<p className="text-3xl md:text-5xl font-black text-gray-900 mb-2">{s.val}</p>
|
||||
<p className="text-[10px] md:text-xs font-black text-[#0284c7] uppercase tracking-[0.2em]">{s.label}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-24">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">Miért válassza a BlueWave-et?</h2>
|
||||
<p className="text-xl text-gray-600">Szakértelem, minőség és megbízhatóság egy helyen.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-12 items-center">
|
||||
<img src="https://images.unsplash.com/photo-1581092160562-40aa08e78837?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80" alt="Engineer" className="rounded-3xl shadow-2xl" />
|
||||
<div className="space-y-8">
|
||||
{[
|
||||
{ title: 'Szakértő Mérnökcsapat', text: 'Saját, magasan képzett mérnökeink tervezik meg rendszerét a maximális hatékonyság érdekében.' },
|
||||
{ title: 'Gyors Kivitelezés', text: 'A szerződéskötéstől számított 30 napon belül telepítjük rendszerét.' },
|
||||
{ title: 'Folyamatos Támogatás', text: 'Telepítés után sem engedjük el a kezét, távfelügyeletet és karbantartást biztosítunk.' }
|
||||
].map((feat, i) => (
|
||||
<div key={i} className="flex gap-4">
|
||||
<div className="w-8 h-8 rounded-full bg-[#0284c7] flex-shrink-0 flex items-center justify-center text-white font-bold mt-1">
|
||||
{i + 1}
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold text-gray-900 mb-2">{feat.title}</h3>
|
||||
<p className="text-gray-600 leading-relaxed">{feat.text}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<button onClick={() => setActivePage('about')} className="mt-4 text-[#0284c7] font-bold flex items-center hover:underline">
|
||||
Tudjon meg többet rólunk <ArrowRight className="w-5 h-5 ml-2" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Featured Section */}
|
||||
<section className="py-24 bg-gray-50">
|
||||
<div className="max-w-7xl mx-auto px-4">
|
||||
<div className="flex flex-col md:flex-row justify-between items-end mb-16 gap-6">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="text-sm font-black text-[#0284c7] uppercase tracking-[0.3em] mb-4">Prémium Szolgáltatás</h2>
|
||||
<p className="text-3xl md:text-5xl font-black text-gray-900 leading-tight tracking-tighter">Miért a BlueWave a legjobb választás?</p>
|
||||
</div>
|
||||
<button onClick={() => setActivePage('about')} className="text-sm font-bold text-gray-400 hover:text-[#0284c7] transition-colors flex items-center group">
|
||||
Tudjon meg többet rólunk <ChevronRight className="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ icon: Sun, title: 'Csúcskategóriás Panelek', desc: 'Csak Tier-1 besorolású, bizonyítottan tartós napelemeket használunk a legnagyobb hatásfokért.' },
|
||||
{ icon: Battery, title: 'Intelligens Tárolás', desc: 'Hibrid invertereink és akkumulátoros rendszereink révén akár éjszaka is tiszta energiát használhat.' },
|
||||
{ icon: Shield, title: '25 Év Teljes Biztonság', desc: 'Nemcsak a termékekre, hanem a munkavégzésre is kiemelkedő garanciális feltételeket biztosítunk.' }
|
||||
].map((f, i) => (
|
||||
<div key={i} className="bg-white p-10 rounded-[32px] shadow-sm hover:shadow-xl transition-all group">
|
||||
<div className="w-16 h-16 bg-sky-50 rounded-2xl flex items-center justify-center text-[#0284c7] mb-8 group-hover:bg-[#0284c7] group-hover:text-white transition-colors">
|
||||
<f.icon className="w-8 h-8" />
|
||||
</div>
|
||||
<h3 className="text-xl font-black text-gray-900 mb-4 uppercase tracking-tighter">{f.title}</h3>
|
||||
<p className="text-gray-500 text-sm leading-relaxed font-medium">{f.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* SERVICES PAGE */}
|
||||
{/* --- SERVICES PAGE --- */}
|
||||
{activePage === 'services' && (
|
||||
<div className="py-20 bg-gray-50 min-h-screen">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="py-24 bg-white min-h-screen px-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="text-center mb-20">
|
||||
<span className="text-[#0284c7] font-bold uppercase tracking-wider text-sm mb-2 block">Megoldásaink</span>
|
||||
<h2 className="text-4xl md:text-5xl font-extrabold text-gray-900 mb-6">Minden igényre van válaszunk</h2>
|
||||
<p className="text-xl text-gray-600 max-w-3xl mx-auto">Legyen szó kis családi házról vagy hatalmas ipari létesítményről, mi megtaláljuk az optimális rendszert.</p>
|
||||
<span className="text-[#0284c7] font-black uppercase tracking-[0.4em] text-xs mb-4 block">Szolgáltatások</span>
|
||||
<h2 className="text-4xl md:text-6xl font-black text-gray-900 mb-8 tracking-tighter">Komplex Energetikai Megoldások</h2>
|
||||
<p className="text-lg text-gray-500 max-w-3xl mx-auto font-medium leading-relaxed">Saját mérnöki csapattal, alvállalkozók nélkül végezzük a teljes kivitelezést.</p>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-16">
|
||||
{/* Residential */}
|
||||
<div className="group bg-white rounded-3xl overflow-hidden shadow-xl hover:shadow-2xl transition-all duration-300 border border-gray-100">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12">
|
||||
<div className="bg-gray-900 rounded-[40px] overflow-hidden group shadow-2xl">
|
||||
<div className="h-80 overflow-hidden relative">
|
||||
<div className="absolute inset-0 bg-black/20 group-hover:bg-black/10 transition-colors z-10"></div>
|
||||
<img src="https://images.unsplash.com/photo-1613665813446-82a78c468a1d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Residential" className="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700" />
|
||||
<div className="absolute bottom-6 left-6 z-20">
|
||||
<span className="bg-white px-4 py-1 rounded-full text-sm font-bold text-[#0284c7] mb-2 inline-block">Lakossági</span>
|
||||
<h3 className="text-3xl font-bold text-white">Családi Házak</h3>
|
||||
</div>
|
||||
<img src="https://images.unsplash.com/photo-1613665813446-82a78c468a1d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Res" className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700 opacity-80" />
|
||||
<div className="absolute top-8 left-8 bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20 text-white text-[10px] font-black uppercase tracking-widest">Családi Házak</div>
|
||||
</div>
|
||||
<div className="p-10">
|
||||
<p className="text-gray-600 mb-8 text-lg leading-relaxed">
|
||||
Csökkentse otthona energiafüggőségét és növelje ingatlana értékét. Rendszereink diszkrétek, esztétikusak és okosotthon-kompatibilisek.
|
||||
</p>
|
||||
<div className="grid sm:grid-cols-2 gap-4 mb-8">
|
||||
{['Rezsi nullázása', 'Hibrid Inverterek', 'Okos monitorozás', 'Elektromos autó töltés'].map((item, i) => (
|
||||
<div key={i} className="flex items-center text-gray-700 font-medium">
|
||||
<CheckCircle className="w-5 h-5 text-green-500 mr-3" /> {item}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button onClick={() => setActivePage('contact')} className="w-full py-4 border-2 border-[#0284c7] text-[#0284c7] font-bold rounded-xl hover:bg-[#0284c7] hover:text-white transition-all">
|
||||
Ajánlatkérés Családi Házra
|
||||
<div className="p-10 md:p-12">
|
||||
<h3 className="text-3xl font-black text-white mb-6 uppercase tracking-tighter">Lakossági Napelem</h3>
|
||||
<p className="text-gray-400 mb-10 leading-relaxed font-medium">Optimalizálja otthona fenntartási költségeit. Teljes körű engedélyeztetés, H-tarifa ügyintézés és statikai tervezés.</p>
|
||||
<button onClick={() => setActivePage('contact')} className="w-full py-5 border-2 border-white/10 text-white font-black rounded-2xl hover:bg-white hover:text-gray-900 transition-all uppercase tracking-widest text-xs">
|
||||
Kérjen lakossági ajánlatot
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Industrial */}
|
||||
<div className="group bg-white rounded-3xl overflow-hidden shadow-xl hover:shadow-2xl transition-all duration-300 border border-gray-100">
|
||||
<div className="bg-[#0284c7] rounded-[40px] overflow-hidden group shadow-2xl">
|
||||
<div className="h-80 overflow-hidden relative">
|
||||
<div className="absolute inset-0 bg-black/20 group-hover:bg-black/10 transition-colors z-10"></div>
|
||||
<img src="https://images.unsplash.com/photo-1624397640148-949b1732bb0a?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Commercial" className="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700" />
|
||||
<div className="absolute bottom-6 left-6 z-20">
|
||||
<span className="bg-white px-4 py-1 rounded-full text-sm font-bold text-[#0284c7] mb-2 inline-block">Ipari</span>
|
||||
<h3 className="text-3xl font-bold text-white">Vállalatok & Üzemek</h3>
|
||||
</div>
|
||||
<img src="https://images.unsplash.com/photo-1624397640148-949b1732bb0a?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Comm" className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700 opacity-80" />
|
||||
<div className="absolute top-8 left-8 bg-white/20 backdrop-blur-md px-4 py-2 rounded-full border border-white/30 text-white text-[10px] font-black uppercase tracking-widest">Ipar & Mezőgazdaság</div>
|
||||
</div>
|
||||
<div className="p-10">
|
||||
<p className="text-gray-600 mb-8 text-lg leading-relaxed">
|
||||
Optimalizálja vállalkozása működési költségeit. Nagy teljesítményű rendszerek, amelyek fedezik a gépek és üzemcsarnokok energiaigényét.
|
||||
</p>
|
||||
<div className="grid sm:grid-cols-2 gap-4 mb-8">
|
||||
{['Gyors megtérülés', '50kW - 5MW teljesítmény', 'ESG megfelelőség', 'Saját transzformátor'].map((item, i) => (
|
||||
<div key={i} className="flex items-center text-gray-700 font-medium">
|
||||
<CheckCircle className="w-5 h-5 text-green-500 mr-3" /> {item}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button onClick={() => setActivePage('contact')} className="w-full py-4 border-2 border-[#0284c7] text-[#0284c7] font-bold rounded-xl hover:bg-[#0284c7] hover:text-white transition-all">
|
||||
Ipari Konzultáció Kérése
|
||||
<div className="p-10 md:p-12 text-white">
|
||||
<h3 className="text-3xl font-black mb-6 uppercase tracking-tighter">Vállalati Rendszerek</h3>
|
||||
<p className="text-sky-100 mb-10 leading-relaxed font-medium">Csökkentse cége rezsiköltségét ipari méretű naperőművekkel. Megtérülési számítások és pályázati tanácsadás professzionálisan.</p>
|
||||
<button onClick={() => setActivePage('contact')} className="w-full py-5 bg-white text-[#0284c7] font-black rounded-2xl hover:bg-gray-900 hover:text-white transition-all uppercase tracking-widest text-xs">
|
||||
Ipari konzultáció kérése
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -291,138 +250,155 @@ export const BlueWave: React.FC = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* ABOUT PAGE */}
|
||||
{/* --- BLOG PAGE --- */}
|
||||
{activePage === 'blog' && (
|
||||
<div className="py-24 bg-gray-50 min-h-screen px-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="text-center mb-20">
|
||||
<span className="text-[#0284c7] font-black uppercase tracking-[0.4em] text-xs mb-4 block">Tudástár</span>
|
||||
<h2 className="text-4xl md:text-6xl font-black text-gray-900 tracking-tighter">Friss hírek & Cikkek</h2>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ date: '2024.03.15', title: 'Új napelemes pályázatok: Mire számíthatunk?', img: 'https://images.unsplash.com/photo-1559302504-64aae6ca6b6d?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80' },
|
||||
{ date: '2024.03.02', title: 'Hibrid vagy szigetüzemű rendszer? Segítünk dönteni.', img: 'https://images.unsplash.com/photo-1509391366360-2e959784a276?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80' },
|
||||
{ date: '2024.02.20', title: 'Hogyan tartsuk karban napelemes rendszerünket?', img: 'https://images.unsplash.com/photo-1548550023-2bdb3c5beed7?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80' }
|
||||
].map((post, i) => (
|
||||
<article key={i} className="bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all group">
|
||||
<div className="h-60 overflow-hidden">
|
||||
<img src={post.img} alt={post.title} className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500" />
|
||||
</div>
|
||||
<div className="p-8">
|
||||
<time className="text-[10px] font-black text-[#0284c7] uppercase tracking-widest">{post.date}</time>
|
||||
<h3 className="text-xl font-black text-gray-900 mt-3 mb-6 leading-tight uppercase tracking-tighter">{post.title}</h3>
|
||||
<button className="flex items-center text-xs font-black text-gray-400 hover:text-[#0284c7] uppercase tracking-widest transition-colors">
|
||||
Tovább olvasom <ArrowRight className="w-4 h-4 ml-2" />
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* --- ABOUT PAGE --- */}
|
||||
{activePage === 'about' && (
|
||||
<div className="py-20 bg-white">
|
||||
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
|
||||
<div className="inline-block p-3 rounded-full bg-sky-100 mb-6 text-[#0284c7]">
|
||||
<Sun className="w-8 h-8" />
|
||||
</div>
|
||||
<h2 className="text-4xl font-extrabold text-gray-900 mb-8">A BlueWave Küldetése</h2>
|
||||
<p className="text-xl text-gray-700 leading-relaxed mb-12">
|
||||
A BlueWave Solar Kft. 2015-ben azzal a céllal alakult, hogy elérhetővé tegye a napenergiát mindenki számára. Hiszünk abban, hogy a fenntarthatóság nem luxus, hanem a jövő záloga. Csapatunk okleveles mérnökökből, pályázati szakértőkből és tapasztalt kivitelezőkből áll.
|
||||
</p>
|
||||
|
||||
<div className="bg-gradient-to-br from-[#0f172a] to-[#1e293b] rounded-3xl p-12 text-white shadow-2xl mb-16 relative overflow-hidden">
|
||||
<div className="relative z-10 grid grid-cols-1 md:grid-cols-3 gap-12">
|
||||
<div>
|
||||
<div className="text-5xl font-bold text-[#38bdf8] mb-2">500+</div>
|
||||
<div className="text-gray-400 font-medium uppercase tracking-wide text-sm">Telepített rendszer</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-5xl font-bold text-[#38bdf8] mb-2">15MW</div>
|
||||
<div className="text-gray-400 font-medium uppercase tracking-wide text-sm">Össz teljesítmény</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-5xl font-bold text-[#38bdf8] mb-2">100%</div>
|
||||
<div className="text-gray-400 font-medium uppercase tracking-wide text-sm">Ügyfél elégedettség</div>
|
||||
</div>
|
||||
<div className="py-24 bg-white min-h-screen px-4">
|
||||
<div className="max-w-5xl mx-auto">
|
||||
<h2 className="text-4xl md:text-7xl font-black text-gray-900 mb-12 tracking-tighter uppercase leading-[0.9]">Több mint egy <br/><span className="text-[#0284c7]">kivitelező cég.</span></h2>
|
||||
<div className="grid md:grid-cols-2 gap-16 items-center">
|
||||
<div className="space-y-6">
|
||||
<p className="text-lg text-gray-600 leading-relaxed font-medium">A BlueWave Solar azért jött létre, hogy a megújuló energiát elérhetővé, egyszerűvé és átláthatóvá tegye mindenki számára. Csapatunk több mint 10 éves tapasztalattal rendelkezik a villamosenergia-szektorban.</p>
|
||||
<p className="text-lg text-gray-600 leading-relaxed font-medium">Saját mérnökeinkkel és telepítő csapatunkkal garantáljuk, hogy minden rendszerünk évtizedekig hibátlanul működjön. Számunkra nemcsak a panelek felrakása a cél, hanem egy fenntarthatóbb jövő építése.</p>
|
||||
<div className="pt-10 flex gap-6">
|
||||
<div className="p-4 bg-sky-50 rounded-2xl border border-sky-100">
|
||||
<p className="text-2xl font-black text-[#0284c7]">10+</p>
|
||||
<p className="text-[10px] font-black text-gray-400 uppercase tracking-widest">Év tapasztalat</p>
|
||||
</div>
|
||||
<div className="p-4 bg-sky-50 rounded-2xl border border-sky-100">
|
||||
<p className="text-2xl font-black text-[#0284c7]">HU</p>
|
||||
<p className="text-[10px] font-black text-gray-400 uppercase tracking-widest">Országos lefedettség</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* Background decorations */}
|
||||
<div className="absolute top-0 right-0 w-64 h-64 bg-[#38bdf8] rounded-full filter blur-[100px] opacity-20"></div>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8 text-left">
|
||||
<div className="bg-gray-50 p-8 rounded-2xl">
|
||||
<h3 className="font-bold text-xl mb-3">Minőség</h3>
|
||||
<p className="text-gray-600">Kizárólag minősített, prémium gyártók termékeit használjuk, hogy rendszere évtizedekig működjön.</p>
|
||||
</div>
|
||||
<div className="bg-gray-50 p-8 rounded-2xl">
|
||||
<h3 className="font-bold text-xl mb-3">Innováció</h3>
|
||||
<p className="text-gray-600">Folyamatos követjük a technológia fejlődését, hogy a legmodernebb megoldásokat kínálhassuk.</p>
|
||||
</div>
|
||||
<div className="bg-gray-50 p-8 rounded-2xl">
|
||||
<h3 className="font-bold text-xl mb-3">Garancia</h3>
|
||||
<p className="text-gray-600">A kivitelezésre és a termékekre is kiemelkedő garanciális feltételeket biztosítunk.</p>
|
||||
<div className="rounded-[40px] overflow-hidden shadow-2xl">
|
||||
<img src="https://images.unsplash.com/photo-1521737604893-d14cc237f11d?ixlib=rb-4.0.3&auto=format&fit=crop&w=1000&q=80" alt="Team" className="w-full h-full object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CONTACT PAGE */}
|
||||
{/* --- CONTACT PAGE --- */}
|
||||
{activePage === 'contact' && (
|
||||
<div className="py-20 bg-[#f8fafc] min-h-screen">
|
||||
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid lg:grid-cols-5 gap-10 bg-white rounded-3xl shadow-xl overflow-hidden border border-gray-100">
|
||||
{/* Left Panel */}
|
||||
<div className="lg:col-span-2 bg-[#0284c7] p-10 text-white flex flex-col justify-between relative overflow-hidden">
|
||||
<div className="py-20 bg-gray-50 min-h-screen px-4">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-5 bg-white rounded-[48px] shadow-2xl overflow-hidden border border-gray-100">
|
||||
{/* Contact Info Card */}
|
||||
<div className="lg:col-span-2 bg-[#0284c7] p-10 md:p-14 text-white flex flex-col justify-between relative overflow-hidden">
|
||||
<div className="relative z-10">
|
||||
<h3 className="text-2xl font-bold mb-6">Lépjen velünk kapcsolatba</h3>
|
||||
<p className="text-sky-100 mb-8">
|
||||
Töltse ki az űrlapot egy ingyenes, kötelezettségmentes előzetes kalkulációért. Mérnök kollégánk 24 órán belül keresni fogja.
|
||||
</p>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-center gap-4">
|
||||
<Phone className="w-6 h-6 text-sky-200" />
|
||||
<span className="font-medium">+36 30 999 8888</span>
|
||||
<h3 className="text-3xl font-black mb-8 tracking-tighter uppercase">Keressen bizalommal</h3>
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-start gap-5">
|
||||
<div className="p-3 bg-white/10 rounded-xl"><Phone className="w-6 h-6" /></div>
|
||||
<div><p className="text-[10px] font-bold text-sky-200 uppercase tracking-widest mb-1">Hívjon minket</p><p className="text-lg font-bold">+36 30 999 8888</p></div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Mail className="w-6 h-6 text-sky-200" />
|
||||
<span className="font-medium">info@bluewave-solar.demo</span>
|
||||
<div className="flex items-start gap-5">
|
||||
<div className="p-3 bg-white/10 rounded-xl"><Mail className="w-6 h-6" /></div>
|
||||
<div><p className="text-[10px] font-bold text-sky-200 uppercase tracking-widest mb-1">Írjon nekünk</p><p className="text-lg font-bold">info@bluewave-solar.hu</p></div>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<Home className="w-6 h-6 text-sky-200" />
|
||||
<span className="font-medium">1117 Budapest, Napelem u. 1.</span>
|
||||
<div className="flex items-start gap-5">
|
||||
<div className="p-3 bg-white/10 rounded-xl"><MapPin className="w-6 h-6" /></div>
|
||||
<div><p className="text-[10px] font-bold text-sky-200 uppercase tracking-widest mb-1">Irodánk</p><p className="text-lg font-bold">1117 Budapest, Napelem u. 1.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative z-10 mt-12">
|
||||
<p className="text-sm text-sky-200 opacity-80">
|
||||
Nyitvatartás: H-P 8:00 - 17:00
|
||||
</p>
|
||||
|
||||
<div className="mt-16 pt-10 border-t border-white/10 relative z-10">
|
||||
<div className="flex gap-4">
|
||||
<button className="w-12 h-12 bg-white/10 rounded-full flex items-center justify-center hover:bg-white/20 transition-all"><Share2 className="w-5 h-5" /></button>
|
||||
<button className="w-12 h-12 bg-white/10 rounded-full flex items-center justify-center hover:bg-white/20 transition-all"><Play className="w-5 h-5" /></button>
|
||||
</div>
|
||||
</div>
|
||||
{/* Circle decorations */}
|
||||
<div className="absolute -bottom-10 -right-10 w-48 h-48 bg-sky-500 rounded-full opacity-50"></div>
|
||||
<div className="absolute top-10 right-10 w-20 h-20 bg-sky-400 rounded-full opacity-30"></div>
|
||||
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute -bottom-20 -right-20 w-64 h-64 bg-sky-500 rounded-full opacity-30 blur-3xl"></div>
|
||||
</div>
|
||||
|
||||
{/* Right Panel - Form */}
|
||||
<div className="lg:col-span-3 p-10">
|
||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Ingyenes Ajánlatkérés</h2>
|
||||
{/* FORM SECTION */}
|
||||
<div className="lg:col-span-3 p-10 md:p-14 bg-[#0f172a]">
|
||||
<h2 className="text-2xl md:text-3xl font-black text-white mb-10 tracking-tighter uppercase">Ajánlatkérés</h2>
|
||||
<form className="space-y-6">
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-700 mb-2">Teljes Név</label>
|
||||
<input type="text" className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-[#0284c7] focus:border-transparent outline-none transition-all bg-gray-50 focus:bg-white text-gray-900" placeholder="Kovács János" />
|
||||
<label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Teljes Név</label>
|
||||
<input type="text" className="w-full px-5 py-4 rounded-2xl border-none bg-white text-black font-bold focus:ring-4 focus:ring-[#0ea5e9]/30 outline-none transition-all placeholder:text-gray-300" placeholder="Kovács János" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-700 mb-2">Telefonszám</label>
|
||||
<input type="tel" className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-[#0284c7] focus:border-transparent outline-none transition-all bg-gray-50 focus:bg-white text-gray-900" placeholder="+36 30 123 4567" />
|
||||
<label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Telefonszám</label>
|
||||
<input type="tel" className="w-full px-5 py-4 rounded-2xl border-none bg-white text-black font-bold focus:ring-4 focus:ring-[#0ea5e9]/30 outline-none transition-all placeholder:text-gray-300" placeholder="+36 30 ..." />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-700 mb-2">Email Cím</label>
|
||||
<input type="email" className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-[#0284c7] focus:border-transparent outline-none transition-all bg-gray-50 focus:bg-white text-gray-900" placeholder="janos@pelda.hu" />
|
||||
</div>
|
||||
|
||||
<div className="p-6 bg-sky-50 rounded-xl border border-sky-100">
|
||||
<div className="flex items-center gap-2 mb-4 text-[#0284c7] font-bold">
|
||||
<Calculator className="w-5 h-5" /> Gyors Kalkulátor Adatok
|
||||
<div className="p-6 md:p-8 bg-[#1e293b] rounded-[32px] border border-gray-800 space-y-6">
|
||||
<div className="flex items-center gap-3 text-[#38bdf8] font-black text-xs uppercase tracking-widest">
|
||||
<Calculator className="w-5 h-5" /> Villám Kalkulátor
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-6">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-700 mb-2">Havi villanyszámla (kb.)</label>
|
||||
<input type="number" className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-[#0284c7] outline-none bg-white text-gray-900" placeholder="Pl: 25000" />
|
||||
<label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Havi villanyszámla (Ft)</label>
|
||||
<input type="number" className="w-full px-5 py-4 rounded-2xl border-none bg-white text-black font-bold placeholder:text-gray-300" placeholder="Pl: 15.000" />
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-700 mb-2">Telepítés Helyszíne</label>
|
||||
<input type="text" className="w-full px-4 py-3 rounded-lg border border-gray-200 focus:ring-2 focus:ring-[#0284c7] outline-none bg-white text-gray-900" placeholder="Város / Irányítószám" />
|
||||
<label className="block text-[10px] font-black text-gray-400 uppercase tracking-widest mb-2 ml-1">Helyszín</label>
|
||||
<input type="text" className="w-full px-5 py-4 rounded-2xl border-none bg-white text-black font-bold placeholder:text-gray-300" placeholder="Irányítószám / Város" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="pt-2">
|
||||
<button type="button" className="w-full bg-[#0284c7] hover:bg-[#0369a1] text-white font-bold py-4 rounded-xl transition-all shadow-lg hover:shadow-xl transform hover:-translate-y-1">
|
||||
Díjmentes Kalkuláció Kérése
|
||||
<div className="pt-4">
|
||||
<button type="button" className="w-full bg-[#0284c7] hover:bg-white hover:text-gray-900 text-white font-black py-6 rounded-2xl shadow-2xl transition-all active:scale-95 uppercase tracking-[0.2em] text-xs">
|
||||
Ingyenes Kalkuláció Kérése
|
||||
</button>
|
||||
<p className="text-center text-xs text-gray-500 mt-4">
|
||||
Az ajánlatkérés nem jár kötelezettséggel. Adatvédelmi irányelveinket elfogadom.
|
||||
</p>
|
||||
<p className="text-center text-gray-500 text-[10px] mt-6 font-bold uppercase tracking-widest">Kollégánk 24 órán belül keresni fogja Önt.</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Google Map Placeholder */}
|
||||
<div className="mt-12 bg-white rounded-[40px] overflow-hidden h-[400px] shadow-sm border border-gray-100 relative group">
|
||||
<div className="absolute inset-0 bg-gray-200 flex items-center justify-center overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1526778548025-fa2f459cd5c1?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Map" className="w-full h-full object-cover opacity-50 grayscale group-hover:grayscale-0 transition-all duration-700" />
|
||||
<div className="absolute inset-0 bg-sky-900/10 group-hover:bg-transparent transition-all"></div>
|
||||
<div className="relative z-10 bg-white p-6 rounded-3xl shadow-2xl text-center border border-gray-100">
|
||||
<MapPin className="w-10 h-10 text-[#0284c7] mx-auto mb-3" />
|
||||
<p className="font-black text-gray-900 uppercase tracking-widest text-xs">Interaktív Térkép</p>
|
||||
<p className="text-[10px] text-gray-400 font-bold mt-1">1117 BUDAPEST, NAPELEM U. 1.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -431,44 +407,62 @@ export const BlueWave: React.FC = () => {
|
||||
</main>
|
||||
|
||||
{/* Footer */}
|
||||
<footer className="bg-[#0f172a] text-white py-16 border-t border-gray-800">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid md:grid-cols-4 gap-12 mb-12">
|
||||
<div className="col-span-1 md:col-span-2">
|
||||
<div className="flex items-center mb-6">
|
||||
<div className="bg-gradient-to-tr from-[#0284c7] to-[#0ea5e9] p-2 rounded-lg mr-3">
|
||||
<footer className="bg-gray-900 text-white py-20 border-t border-gray-800 px-4">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-16">
|
||||
<div className="sm:col-span-2">
|
||||
<div className="flex items-center mb-8">
|
||||
<div className="bg-gradient-to-tr from-[#0284c7] to-[#0ea5e9] p-3 rounded-2xl mr-4">
|
||||
<Sun className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<span className="text-2xl font-bold">BlueWave<span className="text-[#38bdf8]">Solar</span></span>
|
||||
<span className="text-2xl font-black uppercase tracking-tighter">BlueWave<span className="text-[#38bdf8]">Solar</span></span>
|
||||
</div>
|
||||
<p className="text-gray-400 max-w-sm leading-relaxed">
|
||||
Magyarország vezető napenergia szolgáltatója. Célunk, hogy ügyfeleink számára energiafüggetlenséget és fenntartható jövőt biztosítsunk.
|
||||
<p className="text-gray-400 max-w-sm text-sm leading-relaxed font-medium mb-10">
|
||||
A jövő energiája ma kezdődik. Segítünk elszakadni a hálózati függőségtől és csökkenteni ökológiai lábnyomát professzionális technológiával.
|
||||
</p>
|
||||
<div className="flex gap-4">
|
||||
<div className="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-[#0284c7] transition-all cursor-pointer"><FacebookIcon className="w-4 h-4" /></div>
|
||||
<div className="w-10 h-10 rounded-full bg-gray-800 flex items-center justify-center hover:bg-[#0284c7] transition-all cursor-pointer"><InstagramIcon className="w-4 h-4" /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg mb-6 text-white">Navigáció</h4>
|
||||
<ul className="space-y-3 text-gray-400">
|
||||
<li onClick={() => setActivePage('home')} className="cursor-pointer hover:text-[#38bdf8] transition-colors">Főoldal</li>
|
||||
<li onClick={() => setActivePage('services')} className="cursor-pointer hover:text-[#38bdf8] transition-colors">Megoldások</li>
|
||||
<li onClick={() => setActivePage('about')} className="cursor-pointer hover:text-[#38bdf8] transition-colors">Rólunk</li>
|
||||
<li onClick={() => setActivePage('contact')} className="cursor-pointer hover:text-[#38bdf8] transition-colors">Kapcsolat</li>
|
||||
<h4 className="font-black text-xs mb-8 text-white uppercase tracking-[0.3em]">Navigáció</h4>
|
||||
<ul className="space-y-4 text-xs font-bold text-gray-500 uppercase tracking-widest">
|
||||
<li onClick={() => setActivePage('home')} className="cursor-pointer hover:text-white transition-colors">Főoldal</li>
|
||||
<li onClick={() => setActivePage('services')} className="cursor-pointer hover:text-white transition-colors">Megoldások</li>
|
||||
<li onClick={() => setActivePage('blog')} className="cursor-pointer hover:text-white transition-colors">Blog</li>
|
||||
<li onClick={() => setActivePage('contact')} className="cursor-pointer hover:text-white transition-colors">Kapcsolat</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-lg mb-6 text-white">Kapcsolat</h4>
|
||||
<div className="space-y-3 text-gray-400">
|
||||
<p>1117 Budapest, Napelem u. 1.</p>
|
||||
<p>+36 30 999 8888</p>
|
||||
<p>info@bluewave-solar.demo</p>
|
||||
</div>
|
||||
<h4 className="font-black text-xs mb-8 text-white uppercase tracking-[0.3em]">Kapcsolat</h4>
|
||||
<ul className="space-y-4 text-xs font-bold text-gray-500">
|
||||
<li className="flex items-center gap-3"><MapPin className="w-4 h-4 text-[#38bdf8]" /> 1117 Budapest, Napelem u. 1.</li>
|
||||
<li className="flex items-center gap-3"><Phone className="w-4 h-4 text-[#38bdf8]" /> +36 30 999 8888</li>
|
||||
<li className="flex items-center gap-3"><Mail className="w-4 h-4 text-[#38bdf8]" /> info@bluewave-solar.hu</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-gray-800 pt-8 flex flex-col md:flex-row justify-between items-center text-gray-500 text-sm">
|
||||
<p>© 2024 BlueWave Solar Kft. Minden jog fenntartva.</p>
|
||||
<p>Demonstrációs weboldal - MotionWeb Pro csomag</p>
|
||||
<div className="border-t border-gray-800 mt-20 pt-10 flex flex-col md:flex-row justify-between items-center gap-6">
|
||||
<p className="text-gray-600 text-[10px] font-bold uppercase tracking-widest">© 2024 BlueWave Solar Kft. Minden jog fenntartva.</p>
|
||||
<div className="flex gap-8 text-[10px] font-bold text-gray-600 uppercase tracking-widest">
|
||||
<span className="hover:text-white cursor-pointer transition-colors">Adatvédelem</span>
|
||||
<span className="hover:text-white cursor-pointer transition-colors">ÁSZF</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// Internal social icons to avoid extra lucide-react dependency issues in demo
|
||||
const Shield = ({ className }: { className?: string }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
||||
);
|
||||
const FacebookIcon = ({ className }: { className?: string }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></svg>
|
||||
);
|
||||
const InstagramIcon = ({ className }: { className?: string }) => (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><rect width="20" height="20" x="2" y="2" rx="5" ry="5"/><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"/><line x1="17.5" x2="17.51" y1="6.5" y2="6.5"/></svg>
|
||||
);
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ArrowLeft, Shield, Lock, Eye, Server, Cpu, Globe, ChevronDown, PlayCircle, Fingerprint, Scan, Activity, Radio, Terminal, Box, Building2, Users, MapPin } from 'lucide-react';
|
||||
|
||||
import React, { useEffect, useState, useRef } from 'react';
|
||||
import {
|
||||
ArrowLeft, Shield, Lock, Eye, Server, Cpu, Globe,
|
||||
ChevronRight, PlayCircle, Fingerprint, Scan, Activity,
|
||||
Radio, Terminal, Box, Building2, Users, MapPin,
|
||||
Menu, X, Zap, ShieldCheck, AlertCircle, Cpu as Chip,
|
||||
Network, Database, HardDrive, ShieldAlert, Key,
|
||||
ArrowRight, ShieldCheck as Verified, Loader2
|
||||
} from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const Steelguard: React.FC = () => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [activeTab, setActiveTab] = useState<'home' | 'solutions' | 'hardware' | 'sectors' | 'company'>('home');
|
||||
const [activePage, setActivePage] = useState<'home' | 'solutions' | 'hardware' | 'security'>('home');
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
// Hero Scanner State
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const [isIdentified, setIsIdentified] = useState(false);
|
||||
const [randomData, setRandomData] = useState({ temp: '32.4', loss: '0.00', nodes: '1248' });
|
||||
// Fix: Use ReturnType<typeof setTimeout> instead of NodeJS.Timeout to avoid namespace errors in browser environment
|
||||
const scanTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
||||
// Fix: Use ReturnType<typeof setInterval> instead of NodeJS.Timeout to avoid namespace errors in browser environment
|
||||
const dataIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => setScrolled(window.scrollY > 20);
|
||||
@@ -12,414 +30,388 @@ export const Steelguard: React.FC = () => {
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
// Reset scroll when changing tabs
|
||||
// Handle Scanning Logic
|
||||
useEffect(() => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}, [activeTab]);
|
||||
if (isHovered) {
|
||||
// Start randomizing data
|
||||
dataIntervalRef.current = setInterval(() => {
|
||||
setRandomData({
|
||||
temp: (Math.random() * 5 + 30).toFixed(1),
|
||||
loss: (Math.random() * 0.5).toFixed(2),
|
||||
nodes: Math.floor(Math.random() * 50 + 1200).toString()
|
||||
});
|
||||
}, 80);
|
||||
|
||||
// Set identification timeout
|
||||
scanTimerRef.current = setTimeout(() => {
|
||||
setIsIdentified(true);
|
||||
if (dataIntervalRef.current) clearInterval(dataIntervalRef.current);
|
||||
}, 1000);
|
||||
} else {
|
||||
// Reset
|
||||
if (scanTimerRef.current) clearTimeout(scanTimerRef.current);
|
||||
if (dataIntervalRef.current) clearInterval(dataIntervalRef.current);
|
||||
setIsIdentified(false);
|
||||
setRandomData({ temp: '32.4', loss: '0.00', nodes: '1248' });
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (scanTimerRef.current) clearTimeout(scanTimerRef.current);
|
||||
if (dataIntervalRef.current) clearInterval(dataIntervalRef.current);
|
||||
};
|
||||
}, [isHovered]);
|
||||
|
||||
const navItems = [
|
||||
{ id: 'home', label: 'Rendszer' },
|
||||
{ id: 'solutions', label: 'Megoldások' },
|
||||
{ id: 'hardware', label: 'Hardver' },
|
||||
{ id: 'security', label: 'Biztonság' }
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="font-sans bg-[#020205] text-gray-100 min-h-screen selection:bg-cyan-500 selection:text-black overflow-x-hidden relative">
|
||||
|
||||
{/* INJECTED STYLES FOR ADVANCED ANIMATIONS */}
|
||||
<style>{`
|
||||
@keyframes grid-move {
|
||||
0% { transform: perspective(500px) rotateX(60deg) translateY(0); }
|
||||
100% { transform: perspective(500px) rotateX(60deg) translateY(40px); }
|
||||
0% { transform: perspective(800px) rotateX(60deg) translateY(0); }
|
||||
100% { transform: perspective(800px) rotateX(60deg) translateY(50px); }
|
||||
}
|
||||
@keyframes scanline {
|
||||
0% { transform: translateY(-100%); }
|
||||
100% { transform: translateY(100%); }
|
||||
0% { transform: translateY(-100%); opacity: 0; }
|
||||
50% { opacity: 1; }
|
||||
100% { transform: translateY(100%); opacity: 0; }
|
||||
}
|
||||
@keyframes blob {
|
||||
0% { transform: translate(0px, 0px) scale(1); }
|
||||
33% { transform: translate(30px, -50px) scale(1.1); }
|
||||
66% { transform: translate(-20px, 20px) scale(0.9); }
|
||||
100% { transform: translate(0px, 0px) scale(1); }
|
||||
@keyframes pulse-slow {
|
||||
0%, 100% { opacity: 0.3; transform: scale(1); }
|
||||
50% { opacity: 0.6; transform: scale(1.05); }
|
||||
}
|
||||
@keyframes pulse-glow {
|
||||
0%, 100% { box-shadow: 0 0 10px rgba(6, 182, 212, 0.2); }
|
||||
50% { box-shadow: 0 0 25px rgba(6, 182, 212, 0.6); }
|
||||
.cyber-grid {
|
||||
background-image:
|
||||
linear-gradient(to right, rgba(6, 182, 212, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(6, 182, 212, 0.1) 1px, transparent 1px);
|
||||
background-size: 50px 50px;
|
||||
mask-image: radial-gradient(circle, black, transparent 80%);
|
||||
}
|
||||
.text-glow:hover {
|
||||
text-shadow: 0 0 10px rgba(34, 211, 238, 0.8), 0 0 20px rgba(34, 211, 238, 0.4);
|
||||
.glass-card {
|
||||
background: rgba(10, 15, 30, 0.4);
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(6, 182, 212, 0.15);
|
||||
box-shadow: 0 10px 40px -10px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.animate-grid-move {
|
||||
animation: grid-move 2s linear infinite;
|
||||
.text-glow {
|
||||
text-shadow: 0 0 15px rgba(34, 211, 238, 0.8), 0 0 30px rgba(34, 211, 238, 0.4);
|
||||
}
|
||||
.animate-blob {
|
||||
animation: blob 10s infinite;
|
||||
.neon-glow-btn:hover {
|
||||
box-shadow: 0 0 25px rgba(34, 211, 238, 0.6), 0 0 50px rgba(34, 211, 238, 0.2);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.animation-delay-2000 {
|
||||
animation-delay: 2s;
|
||||
}
|
||||
.animation-delay-4000 {
|
||||
animation-delay: 4s;
|
||||
}
|
||||
.glass-panel {
|
||||
background: rgba(10, 15, 30, 0.6);
|
||||
backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(6, 182, 212, 0.1);
|
||||
box-shadow: 0 0 15px rgba(0,0,0,0.5);
|
||||
}
|
||||
.cyber-button {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.cyber-button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||
transition: 0.5s;
|
||||
}
|
||||
.cyber-button:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
.clip-path-polygon {
|
||||
.button-clip {
|
||||
clip-path: polygon(10% 0, 100% 0, 100% 70%, 90% 100%, 0 100%, 0 30%);
|
||||
}
|
||||
`}</style>
|
||||
|
||||
{/* Return to Main Site */}
|
||||
<div className="fixed bottom-6 right-6 z-[60] mix-blend-difference">
|
||||
{/* Back to Reality Button */}
|
||||
<div className="fixed bottom-4 right-4 md:bottom-8 md:right-8 z-[60]">
|
||||
<Link to="/#references">
|
||||
<button className="bg-white text-black px-6 py-2 rounded-sm uppercase text-[10px] font-bold tracking-[0.3em] hover:bg-cyan-500 hover:text-white transition-all duration-300 flex items-center group">
|
||||
<ArrowLeft className="w-3 h-3 mr-3 group-hover:-translate-x-1 transition-transform" /> BACK TO REALITY
|
||||
<button className="bg-white/10 backdrop-blur-xl border border-white/20 text-white px-5 py-2.5 rounded-full text-[10px] font-black tracking-[0.2em] hover:bg-white hover:text-black transition-all flex items-center shadow-2xl group">
|
||||
<ArrowLeft className="w-4 h-4 mr-2 group-hover:-translate-x-1 transition-transform" /> VISSZA A PORTFÓLIÓHOZ
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Enterprise Navbar */}
|
||||
<nav className={`fixed w-full z-40 transition-all duration-500 border-b ${scrolled ? 'bg-[#050505]/80 backdrop-blur-xl border-cyan-900/30 py-2' : 'bg-transparent border-transparent py-6'}`}>
|
||||
<div className="max-w-[1600px] mx-auto px-8 flex items-center justify-between">
|
||||
<div className="flex items-center gap-4 group cursor-pointer" onClick={() => setActiveTab('home')}>
|
||||
{/* Animated Background */}
|
||||
<div className="fixed inset-0 z-0 pointer-events-none">
|
||||
<div className="absolute top-0 left-1/2 -translate-x-1/2 w-full h-[1000px] cyber-grid animate-[grid-move_10s_linear_infinite]"></div>
|
||||
<div className="absolute top-[10%] left-[20%] w-[500px] h-[500px] bg-cyan-900/20 blur-[120px] rounded-full animate-pulse-slow"></div>
|
||||
<div className="absolute bottom-[10%] right-[10%] w-[600px] h-[600px] bg-blue-900/10 blur-[150px] rounded-full animate-pulse-slow" style={{ animationDelay: '2s' }}></div>
|
||||
</div>
|
||||
|
||||
{/* Navbar */}
|
||||
<nav className={`fixed w-full z-50 transition-all duration-700 border-b ${scrolled ? 'bg-[#020205]/90 backdrop-blur-2xl border-cyan-500/20 py-2 shadow-[0_10px_30px_rgba(0,0,0,0.5)]' : 'bg-transparent border-transparent py-6'}`}>
|
||||
<div className="max-w-[1400px] mx-auto px-6 md:px-12 flex items-center justify-between">
|
||||
<div className="flex items-center gap-4 cursor-pointer group" onClick={() => setActivePage('home')}>
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-cyan-500 blur-md opacity-20 group-hover:opacity-60 transition-opacity duration-500 animate-pulse"></div>
|
||||
<div className="w-10 h-10 bg-[#0a0a0a] border border-cyan-500/50 flex items-center justify-center relative z-10 clip-path-polygon group-hover:border-cyan-400 transition-colors">
|
||||
<Shield className="text-cyan-400 w-5 h-5" />
|
||||
<div className="absolute inset-0 bg-cyan-500 blur-lg opacity-30 group-hover:opacity-80 transition-opacity"></div>
|
||||
<div className="w-10 h-10 md:w-12 md:h-12 bg-gray-900 border border-cyan-500/50 flex items-center justify-center relative z-10 rounded-xl overflow-hidden group-hover:shadow-[0_0_20px_rgba(34,211,238,0.5)] transition-shadow">
|
||||
<Shield className="text-cyan-400 w-5 h-5 md:w-6 md:h-6" />
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-cyan-500/20 to-transparent"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col text-left">
|
||||
<span className="text-2xl font-bold tracking-tighter text-white font-mono group-hover:text-cyan-400 transition-colors">STEELGUARD</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"></div>
|
||||
<span className="text-[9px] text-cyan-600 tracking-[0.4em] uppercase">Systems Online</span>
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="text-xl md:text-2xl font-black tracking-tighter text-white font-mono uppercase">Steelguard</span>
|
||||
<span className="text-[8px] text-cyan-600 tracking-[0.4em] uppercase font-bold">Enterprise Defense</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden lg:flex items-center space-x-12 text-[10px] font-bold tracking-[0.2em] text-gray-500 font-mono">
|
||||
{[
|
||||
{ id: 'solutions', label: 'Solutions' },
|
||||
{ id: 'hardware', label: 'Hardware' },
|
||||
{ id: 'sectors', label: 'Sectors' },
|
||||
{ id: 'company', label: 'Company' }
|
||||
].map((item) => (
|
||||
<div className="hidden lg:flex items-center space-x-2 font-mono">
|
||||
{navItems.map((item) => (
|
||||
<button
|
||||
key={item.id}
|
||||
onClick={() => setActiveTab(item.id as any)}
|
||||
className={`transition-all relative group py-2 uppercase ${activeTab === item.id ? 'text-cyan-400' : 'hover:text-cyan-400'}`}
|
||||
onClick={() => setActivePage(item.id as any)}
|
||||
className={`px-5 py-2 rounded-lg text-[11px] font-black tracking-widest uppercase transition-all ${activePage === item.id ? 'text-cyan-400 bg-cyan-400/5 shadow-[0_0_20px_rgba(34,211,238,0.2)]' : 'text-gray-500 hover:text-gray-200'}`}
|
||||
>
|
||||
<span className={`text-cyan-800 transition-opacity ${activeTab === item.id ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'} mr-1`}><</span>
|
||||
{item.label}
|
||||
<span className={`text-cyan-800 transition-opacity ${activeTab === item.id ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'} ml-1`}>/></span>
|
||||
<span className={`absolute bottom-0 left-0 h-[1px] bg-cyan-500 transition-all duration-300 shadow-[0_0_10px_#06b6d4] ${activeTab === item.id ? 'w-full' : 'w-0 group-hover:w-full'}`}></span>
|
||||
</button>
|
||||
))}
|
||||
<div className="h-4 w-px bg-gray-800 mx-4"></div>
|
||||
<button className="bg-cyan-600 hover:bg-cyan-500 text-black px-6 py-2.5 rounded-lg text-[10px] font-black uppercase tracking-widest transition-all shadow-lg shadow-cyan-900/20 active:scale-95 hover:shadow-[0_0_30px_rgba(34,211,238,0.7)]">
|
||||
Rendszer Belépés
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-6">
|
||||
<button onClick={() => setActiveTab('home')} className="text-[10px] font-bold text-gray-500 hover:text-white uppercase tracking-[0.2em] hidden sm:block transition-colors border border-transparent hover:border-gray-800 px-4 py-2">
|
||||
Login_Portal
|
||||
</button>
|
||||
<button className="cyber-button bg-cyan-600 hover:bg-cyan-500 text-black px-8 py-3 text-[10px] font-bold uppercase tracking-[0.2em] transition-all shadow-[0_0_20px_rgba(8,145,178,0.4)] hover:shadow-[0_0_30px_rgba(6,182,212,0.6)]">
|
||||
Initialize
|
||||
</button>
|
||||
</div>
|
||||
<button onClick={() => setMobileMenuOpen(!mobileMenuOpen)} className="lg:hidden p-2 text-cyan-400">
|
||||
{mobileMenuOpen ? <X /> : <Menu />}
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Main Content Router Simulation */}
|
||||
<main className="animate-fade-in">
|
||||
{/* Main Content */}
|
||||
<main className="relative z-10 pt-20">
|
||||
|
||||
{/* HOME VIEW */}
|
||||
{activeTab === 'home' && (
|
||||
{activePage === 'home' && (
|
||||
<>
|
||||
<header className="relative h-screen flex items-center justify-center overflow-hidden bg-[#020205]">
|
||||
<div className="absolute inset-0 z-0 overflow-hidden pointer-events-none">
|
||||
<div className="absolute top-[-10%] left-[-10%] w-[600px] h-[600px] bg-blue-900/20 rounded-full mix-blend-screen filter blur-[80px] opacity-30 animate-blob"></div>
|
||||
<div className="absolute top-[20%] right-[-20%] w-[500px] h-[500px] bg-cyan-900/20 rounded-full mix-blend-screen filter blur-[80px] opacity-30 animate-blob animation-delay-2000"></div>
|
||||
<div className="absolute bottom-[-20%] left-[20%] w-[600px] h-[600px] bg-purple-900/10 rounded-full mix-blend-screen filter blur-[80px] opacity-30 animate-blob animation-delay-4000"></div>
|
||||
<div className="absolute inset-0 bg-[linear-gradient(rgba(255,255,255,0.02)_1px,transparent_1px),linear-gradient(90deg,rgba(255,255,255,0.02)_1px,transparent_1px)] bg-[size:50px_50px]"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#020205] via-transparent to-transparent"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-[#020205] via-transparent to-transparent"></div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 max-w-[1400px] mx-auto px-6 grid lg:grid-cols-2 gap-20 items-center mt-20">
|
||||
<div>
|
||||
<div className="inline-flex items-center gap-3 px-4 py-2 border border-cyan-500/30 bg-cyan-900/10 text-cyan-400 text-[10px] font-bold tracking-[0.3em] mb-10 animate-fade-in-up backdrop-blur-md">
|
||||
{/* Hero Section */}
|
||||
<header className="min-h-screen flex items-center px-6 md:px-12 max-w-[1400px] mx-auto pt-10">
|
||||
<div className="grid lg:grid-cols-2 gap-16 items-center">
|
||||
<div className="text-center lg:text-left space-y-8">
|
||||
<div className="inline-flex items-center gap-3 px-4 py-1.5 border border-cyan-500/30 bg-cyan-950/20 text-cyan-400 text-[10px] font-bold tracking-[0.3em] uppercase rounded-full backdrop-blur-md">
|
||||
<Terminal className="w-3 h-3" />
|
||||
<span className="animate-pulse">ESTABLISHING SECURE CONNECTION...</span>
|
||||
<span className="animate-pulse">Rendszer állapota: Aktív</span>
|
||||
</div>
|
||||
<h1 className="text-6xl lg:text-8xl font-bold text-white leading-[0.9] mb-8 font-mono animate-fade-in-up" style={{animationDelay: '0.1s'}}>
|
||||
TOTAL <br/>
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-blue-500 to-purple-600 drop-shadow-[0_0_15px_rgba(6,182,212,0.5)]">DEFENSE</span>
|
||||
|
||||
<h1 className="text-5xl md:text-8xl font-black text-white leading-[0.85] tracking-tighter uppercase font-mono italic">
|
||||
Abszolút <br/>
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-cyan-400 via-blue-500 to-purple-600 drop-shadow-2xl">Digitális</span> <br/>
|
||||
Pajzs
|
||||
</h1>
|
||||
<p className="text-lg text-gray-400 max-w-lg mb-12 leading-relaxed animate-fade-in-up border-l-2 border-cyan-900/50 pl-6" style={{animationDelay: '0.2s'}}>
|
||||
Advanced AI-driven security architecture for enterprise infrastructure. <span className="text-cyan-400 font-bold">Zero-trust protocols</span> and predictive threat neutralization active.
|
||||
|
||||
<p className="text-sm md:text-xl text-gray-400 max-w-xl mx-auto lg:mx-0 font-medium leading-relaxed">
|
||||
Kvantumszintű titkosítás és mesterséges intelligencia alapú fenyegetés-elemzés nagyvállalati környezetre tervezve. <span className="text-cyan-400 font-bold text-glow">Zero-Trust</span> architektúra a teljes biztonságért.
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-6 animate-fade-in-up" style={{animationDelay: '0.3s'}}>
|
||||
<button onClick={() => setActiveTab('solutions')} className="cyber-button bg-white text-black hover:bg-cyan-50 px-10 py-4 text-xs font-bold uppercase tracking-[0.2em] flex items-center gap-4 transition-all hover:pr-12 group shadow-[0_0_20px_rgba(255,255,255,0.3)]">
|
||||
Execute Protocol <ChevronDown className="w-4 h-4 group-hover:translate-y-1 transition-transform" />
|
||||
|
||||
<div className="flex flex-col sm:flex-row justify-center lg:justify-start gap-5">
|
||||
<button className="bg-white text-black px-10 py-5 font-black uppercase tracking-[0.2em] text-xs button-clip hover:bg-cyan-400 transition-all shadow-xl shadow-white/10 neon-glow-btn">
|
||||
Rendszer Indítása
|
||||
</button>
|
||||
<button className="border border-gray-800 hover:border-cyan-500 text-gray-300 hover:text-cyan-400 px-10 py-4 text-xs font-bold uppercase tracking-[0.2em] flex items-center gap-4 transition-all bg-[#0a0a0a]/50 backdrop-blur-sm group hover:shadow-[0_0_15px_rgba(6,182,212,0.3)]">
|
||||
<PlayCircle className="w-4 h-4 group-hover:scale-110 transition-transform" /> Simulation
|
||||
<button className="border border-cyan-500/30 bg-cyan-500/5 text-cyan-400 px-10 py-5 font-black uppercase tracking-[0.2em] text-xs button-clip hover:bg-cyan-500/20 transition-all hover:shadow-[0_0_20px_rgba(34,211,238,0.3)]">
|
||||
Technikai Specifikáció
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="pt-10 flex flex-wrap justify-center lg:justify-start gap-8 opacity-40">
|
||||
<div className="flex items-center gap-2 font-mono text-[10px] font-bold uppercase tracking-widest"><ShieldCheck className="w-4 h-4" /> ISO 27001 Certified</div>
|
||||
<div className="flex items-center gap-2 font-mono text-[10px] font-bold uppercase tracking-widest"><Lock className="w-4 h-4" /> 256-bit AES</div>
|
||||
<div className="flex items-center gap-2 font-mono text-[10px] font-bold uppercase tracking-widest"><Chip className="w-4 h-4" /> hardware-Encrypted</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative hidden lg:block animate-fade-in perspective-1000" style={{animationDelay: '0.5s'}}>
|
||||
<div className="relative w-full aspect-square flex items-center justify-center transform-style-3d rotate-y-12">
|
||||
<div className="absolute w-[80%] h-[80%] border border-cyan-900/40 rounded-full animate-[spin_20s_linear_infinite] shadow-[0_0_30px_rgba(6,182,212,0.1)]"></div>
|
||||
<div className="absolute w-[60%] h-[60%] border-2 border-dashed border-cyan-500/20 rounded-full animate-[spin_15s_linear_infinite_reverse]"></div>
|
||||
<div className="relative z-10 w-[70%] h-[70%] rounded-2xl overflow-hidden border border-cyan-500/30 group shadow-[0_0_50px_rgba(6,182,212,0.15)]">
|
||||
<img src="https://images.unsplash.com/photo-1550751827-4bd374c3f58b?auto=format&fit=crop&w=1000&q=80" alt="Tech Visual" className="w-full h-full object-cover opacity-60 mix-blend-luminosity group-hover:scale-105 transition-transform duration-1000 grayscale" />
|
||||
<div className="absolute inset-0 bg-cyan-900/20 mix-blend-overlay"></div>
|
||||
<div className="absolute top-0 left-0 w-full h-[2px] bg-cyan-400 shadow-[0_0_20px_#22d3ee] animate-[scanline_3s_linear_infinite]"></div>
|
||||
</div>
|
||||
<div className="absolute top-20 -right-10 glass-panel p-4 flex items-center gap-4 animate-[bounce_4s_infinite] border-l-2 border-l-green-500">
|
||||
<Activity className="w-6 h-6 text-green-500 animate-pulse" />
|
||||
<div>
|
||||
<p className="text-[9px] text-gray-400 uppercase tracking-widest font-mono">Status</p>
|
||||
<p className="text-xs font-bold text-green-400 font-mono tracking-wider">OPTIMAL_FLOW</p>
|
||||
{/* HERO INTERACTIVE SCANNER */}
|
||||
<div className="relative hidden lg:block group/hero"
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}>
|
||||
<div className={`glass-card rounded-[40px] aspect-square flex items-center justify-center p-12 relative overflow-hidden transition-all duration-700 border-2 ${isIdentified ? 'border-green-500 shadow-[0_0_60px_rgba(34,197,94,0.3)]' : 'border-cyan-500/20 shadow-[0_0_30px_rgba(34,211,238,0.05)]'}`}>
|
||||
|
||||
<div className={`absolute inset-0 bg-gradient-to-br transition-colors duration-700 ${isIdentified ? 'from-green-500/10' : 'from-cyan-500/10'} to-transparent`}></div>
|
||||
|
||||
{/* Interactive Scanning Line */}
|
||||
<div className={`absolute top-0 left-0 w-full h-[3px] shadow-2xl transition-all duration-300 z-20 ${isIdentified ? 'bg-green-400 shadow-green-500 opacity-0' : isHovered ? 'bg-cyan-400 shadow-cyan-400 animate-[scanline_1s_linear_infinite]' : 'bg-cyan-500/50 shadow-cyan-500/20 animate-[scanline_4s_linear_infinite]'}`}></div>
|
||||
|
||||
{/* Center Module */}
|
||||
<div className="relative z-10 w-full h-full flex items-center justify-center">
|
||||
{/* Orbiting Rings */}
|
||||
<div className={`absolute w-[120%] h-[120%] border rounded-full transition-all duration-700 ${isIdentified ? 'border-green-500/30 animate-[spin_5s_linear_infinite]' : 'border-cyan-500/5 animate-[spin_30s_linear_infinite]'}`}></div>
|
||||
<div className={`absolute w-[80%] h-[80%] border rounded-full transition-all duration-700 ${isIdentified ? 'border-green-500/50 animate-[spin_3s_linear_infinite_reverse]' : 'border-cyan-500/10 animate-[spin_20s_linear_infinite_reverse]'}`}></div>
|
||||
|
||||
{/* Core Fingerprint Circle */}
|
||||
<div className={`w-64 h-64 rounded-full border flex items-center justify-center transition-all duration-700 relative bg-gray-900 ${isIdentified ? 'border-green-400 shadow-[0_0_150px_rgba(34,197,94,0.4)] scale-110' : 'border-cyan-500/30 shadow-[0_0_100px_rgba(6,182,212,0.2)]'}`}>
|
||||
|
||||
{/* Scanning Pulse Overlay */}
|
||||
{isHovered && !isIdentified && (
|
||||
<div className="absolute inset-0 rounded-full bg-cyan-400/20 animate-pulse"></div>
|
||||
)}
|
||||
|
||||
<Fingerprint className={`w-32 h-32 transition-all duration-700 ${isIdentified ? 'text-green-400' : isHovered ? 'text-cyan-300 scale-105' : 'text-cyan-400'}`} />
|
||||
|
||||
{/* Verification Badge */}
|
||||
<div className={`absolute -bottom-4 bg-gray-900 border px-4 py-1.5 rounded-full transition-all duration-700 transform ${isIdentified ? 'scale-100 opacity-100 border-green-500 translate-y-0' : 'scale-50 opacity-0 border-cyan-500 translate-y-4'}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
<Verified className="w-4 h-4 text-green-400" />
|
||||
<span className="text-[10px] font-black text-white uppercase tracking-widest">Access Granted</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Dynamic Data Readouts */}
|
||||
<div className={`absolute top-10 left-10 font-mono text-[9px] leading-tight transition-colors duration-700 ${isIdentified ? 'text-green-400' : isHovered ? 'text-cyan-400' : 'text-cyan-500/60'}`}>
|
||||
CORE_TEMP: {randomData.temp}C<br/>
|
||||
ENCRYPT_MODE: RSA_4096<br/>
|
||||
SEC_LAYER: {isIdentified ? 'V5_ULTRA' : 'V4_ACTIVE'}<br/>
|
||||
{isHovered && <span className={`font-bold ${isIdentified ? 'text-green-300' : 'text-cyan-300'}`}>BIO_AUTH: {isIdentified ? 'VERIFIED' : 'SCANNING...'}</span>}
|
||||
</div>
|
||||
|
||||
<div className={`absolute bottom-10 right-10 font-mono text-[9px] text-right transition-colors duration-700 ${isIdentified ? 'text-green-400' : isHovered ? 'text-cyan-400' : 'text-cyan-500/60'}`}>
|
||||
PACKET_LOSS: {randomData.loss}%<br/>
|
||||
LATENCY: 0.04ms<br/>
|
||||
NODES: {randomData.nodes}/1248<br/>
|
||||
{isHovered && <span className={`font-bold ${isIdentified ? 'text-green-300 animate-pulse' : 'text-cyan-300'}`}>{isIdentified ? 'ENCRYPTION: MAX' : 'HANDSHAKE...'}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section className="py-32 bg-[#020205]">
|
||||
<div className="max-w-[1400px] mx-auto px-6">
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{[
|
||||
{ icon: Eye, title: 'Neural Surveillance', desc: 'Real-time object recognition and behavioral prediction algorithms.' },
|
||||
{ icon: Scan, title: 'Retinal Access', desc: '99.999% accuracy biometric entry points with liveness detection.' },
|
||||
{ icon: Server, title: 'Core Defense', desc: 'Hardened physical and logical shielding for data centers.' },
|
||||
{ icon: Globe, title: 'Global Ops', desc: '24/7 localized threat monitoring from orbit-synced satellites.' },
|
||||
{ icon: Cpu, title: 'IoT Mesh', desc: 'Thousands of interconnected sensors forming an unbreakable web.' },
|
||||
{ icon: Shield, title: 'Hybrid Firewall', desc: 'Simultaneous protection against kinetic and digital intrusion.' },
|
||||
].map((item, i) => (
|
||||
<div key={i} className="group relative bg-[#05070a] border border-gray-800 p-10 overflow-hidden hover:border-cyan-500/50 transition-all duration-500">
|
||||
<div className="relative z-10">
|
||||
<div className="w-14 h-14 bg-[#0a0f18] border border-gray-800 group-hover:border-cyan-500 flex items-center justify-center mb-8 transition-all">
|
||||
<item.icon className="w-6 h-6 text-gray-500 group-hover:text-cyan-400 transition-colors" />
|
||||
</div>
|
||||
<h3 className="text-xl font-bold text-white mb-4 font-mono group-hover:text-cyan-300 transition-colors">{item.title}</h3>
|
||||
<p className="text-gray-500 text-xs leading-relaxed group-hover:text-gray-300 transition-colors font-mono">{item.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Feature Grid */}
|
||||
<section className="py-24 bg-transparent px-6">
|
||||
<div className="max-w-[1400px] mx-auto">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||
{[
|
||||
{ icon: ShieldAlert, title: 'AI Védelem', desc: 'Öntanuló algoritmusok, melyek felismerik a nulladik napi támadásokat is.' },
|
||||
{ icon: Network, title: 'Mesh Hálózat', desc: 'Decentralizált adatforgalom, amely garantálja a 100%-os rendelkezésre állást.' },
|
||||
{ icon: HardDrive, title: 'Adatszéf', desc: 'Fizikailag elkülönített, titkosított adattárolási központok világszerte.' },
|
||||
{ icon: Key, title: 'Biometrikus Auth', desc: 'Többtényezős azonosítás retina, ujjlenyomat és hangalapú validációval.' }
|
||||
].map((f, i) => (
|
||||
<div key={i} className="glass-card p-8 rounded-[32px] hover:border-cyan-400/50 transition-all group cursor-pointer hover:-translate-y-2 hover:shadow-[0_0_35px_rgba(34,211,238,0.2)]">
|
||||
<div className="w-14 h-14 bg-cyan-950/30 rounded-2xl flex items-center justify-center text-cyan-400 mb-6 group-hover:bg-cyan-500 group-hover:text-black transition-all group-hover:shadow-[0_0_20px_rgba(34,211,238,0.6)]">
|
||||
<f.icon className="w-7 h-7" />
|
||||
</div>
|
||||
<h3 className="text-lg font-bold text-white mb-3 uppercase font-mono tracking-tighter group-hover:text-cyan-300 transition-colors">{f.title}</h3>
|
||||
<p className="text-gray-400 text-xs leading-relaxed">{f.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* SOLUTIONS VIEW */}
|
||||
{activeTab === 'solutions' && (
|
||||
<section className="pt-40 pb-20 px-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="flex items-center gap-4 mb-10">
|
||||
<div className="w-12 h-1 bg-cyan-500"></div>
|
||||
<h2 className="text-4xl font-mono font-black uppercase tracking-tighter">Strategic Solutions</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-16 items-center">
|
||||
<div className="space-y-10">
|
||||
<p className="text-xl text-gray-400 font-mono leading-relaxed">
|
||||
We offer a multi-layered security stack designed to neutralize threats before they reach your perimeter.
|
||||
</p>
|
||||
<div className="space-y-6">
|
||||
{[
|
||||
{ title: "Zero Trust Architecture", desc: "Never trust, always verify. Every node is isolated and encrypted." },
|
||||
{ title: "Predictive AI Shield", desc: "Our neural networks predict intrusion patterns with 99.8% accuracy." },
|
||||
{ title: "Cloud Integration", desc: "Seamless security across AWS, Azure, and private data centers." }
|
||||
].map((sol, i) => (
|
||||
<div key={i} className="bg-[#05070a] border-l-4 border-l-cyan-500 p-6">
|
||||
<h4 className="font-bold text-cyan-400 mb-2 font-mono uppercase text-sm">{sol.title}</h4>
|
||||
<p className="text-gray-500 text-xs font-mono">{sol.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* --- SOLUTIONS PAGE --- */}
|
||||
{activePage === 'solutions' && (
|
||||
<div className="py-24 px-6 max-w-[1400px] mx-auto min-h-screen">
|
||||
<div className="flex flex-col md:flex-row justify-between items-end mb-16 gap-8 text-glow">
|
||||
<div className="max-w-2xl">
|
||||
<h2 className="text-sm font-black text-cyan-500 uppercase tracking-[0.5em] mb-4">Megoldásaink</h2>
|
||||
<p className="text-4xl md:text-6xl font-black text-white leading-none tracking-tighter uppercase font-mono">Ipari szintű <br/>biztonsági stack</p>
|
||||
</div>
|
||||
<div className="relative group">
|
||||
<div className="absolute -inset-2 bg-cyan-500 blur-2xl opacity-10 group-hover:opacity-30 transition-opacity"></div>
|
||||
<img src="https://images.unsplash.com/photo-1550751827-4bd374c3f58b?auto=format&fit=crop&w=1200&q=80" alt="Solution" className="rounded-2xl border border-cyan-500/20 relative z-10" />
|
||||
<div className="text-gray-500 font-mono text-xs uppercase tracking-widest border-l border-gray-800 pl-6 hidden md:block">
|
||||
Full Spectrum <br/>Protection Suite v.8.2
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* HARDWARE VIEW */}
|
||||
{activeTab === 'hardware' && (
|
||||
<section className="pt-40 pb-20 px-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="flex items-center gap-4 mb-10">
|
||||
<div className="w-12 h-1 bg-cyan-500"></div>
|
||||
<h2 className="text-4xl font-mono font-black uppercase tracking-tighter">Hardened Hardware</h2>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ icon: Box, name: "Node V4 Unit", img: "https://images.unsplash.com/photo-1518770660439-4636190af475?auto=format&fit=crop&w=800&q=80" },
|
||||
{ icon: Cpu, name: "Neural Processor", img: "https://images.unsplash.com/photo-1591799264318-7e6ef8ddb7ea?auto=format&fit=crop&w=800&q=80" },
|
||||
{ icon: Shield, name: "Quantum Enclosure", img: "https://images.unsplash.com/photo-1544197150-b99a580bb7a8?auto=format&fit=crop&w=800&q=80" }
|
||||
].map((hw, i) => (
|
||||
<div key={i} className="bg-[#05070a] rounded-2xl overflow-hidden border border-gray-800 hover:border-cyan-500/40 transition-all">
|
||||
<img src={hw.img} alt={hw.name} className="h-48 w-full object-cover grayscale opacity-60 hover:grayscale-0 hover:opacity-100 transition-all" />
|
||||
<div className="p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<hw.icon className="w-5 h-5 text-cyan-500" />
|
||||
<span className="font-mono font-bold uppercase text-xs">{hw.name}</span>
|
||||
</div>
|
||||
<button className="w-full py-2 bg-gray-900 border border-gray-800 text-[10px] font-bold uppercase tracking-widest hover:bg-cyan-600 hover:text-black transition-all">View Specs</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* SECTORS VIEW */}
|
||||
{activeTab === 'sectors' && (
|
||||
<section className="pt-40 pb-20 px-8 text-center">
|
||||
<div className="max-w-5xl mx-auto">
|
||||
<h2 className="text-5xl font-mono font-black uppercase tracking-tighter mb-6">Strategic Sectors</h2>
|
||||
<p className="text-gray-400 font-mono mb-20">Steelguard protects the infrastructure that power nations.</p>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-12">
|
||||
{[
|
||||
{ icon: Building2, label: "Enterprise", count: "400+ Nodes" },
|
||||
{ icon: Globe, label: "Government", count: "12 Nations" },
|
||||
{ icon: Shield, label: "Defense", count: "Active Mesh" }
|
||||
].map((sector, i) => (
|
||||
<div key={i} className="flex flex-col items-center group cursor-default">
|
||||
<div className="w-24 h-24 rounded-full border-2 border-gray-800 flex items-center justify-center mb-6 group-hover:border-cyan-500 group-hover:shadow-[0_0_30px_rgba(6,182,212,0.2)] transition-all">
|
||||
<sector.icon className="w-10 h-10 text-gray-500 group-hover:text-cyan-400 transition-colors" />
|
||||
</div>
|
||||
<h3 className="font-mono font-black uppercase text-xl mb-2">{sector.label}</h3>
|
||||
<span className="text-[10px] font-mono text-cyan-600 tracking-widest">{sector.count}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* COMPANY VIEW */}
|
||||
{activeTab === 'company' && (
|
||||
<section className="pt-40 pb-20 px-8">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="grid md:grid-cols-2 gap-16 items-center">
|
||||
<div className="relative">
|
||||
<div className="absolute -inset-4 bg-cyan-500/5 blur-3xl rounded-full"></div>
|
||||
<img src="https://images.unsplash.com/photo-1497366216548-37526070297c?auto=format&fit=crop&w=1000&q=80" alt="Office" className="rounded-3xl relative z-10 opacity-70 grayscale hover:grayscale-0 transition-all" />
|
||||
</div>
|
||||
<div>
|
||||
<span className="text-cyan-500 font-mono text-[10px] tracking-widest block mb-4 uppercase">Origins</span>
|
||||
<h2 className="text-4xl font-mono font-black uppercase mb-8">Engineering <br/>Secured Future</h2>
|
||||
<p className="text-gray-400 font-mono text-sm leading-loose mb-8">
|
||||
Founded in 2042, Steelguard Defense Systems has evolved from a small hardware research lab into a global leader in AI-driven security architecture. Our mission is absolute protection through innovation.
|
||||
</p>
|
||||
<div className="flex items-center gap-8">
|
||||
<div>
|
||||
<p className="text-3xl font-black text-white font-mono">15</p>
|
||||
<p className="text-[9px] text-gray-600 uppercase font-mono tracking-widest">Global Hubs</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-3xl font-black text-white font-mono">850+</p>
|
||||
<p className="text-[9px] text-gray-600 uppercase font-mono tracking-widest">Architects</p>
|
||||
</div>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-10">
|
||||
<div className="glass-card rounded-[48px] overflow-hidden group border-cyan-500/10 hover:shadow-[0_0_40px_rgba(34,211,238,0.1)] transition-all">
|
||||
<div className="h-[400px] relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1558494949-ef010cbdcc51?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Server" className="w-full h-full object-cover grayscale opacity-50 group-hover:scale-110 group-hover:opacity-80 transition-all duration-1000" />
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#020205] via-transparent to-transparent"></div>
|
||||
<div className="absolute top-10 right-10 bg-cyan-500 text-black px-4 py-1.5 rounded-full text-[10px] font-black uppercase tracking-widest group-hover:shadow-[0_0_20px_rgba(34,211,238,0.6)] transition-all">Kritikus Infrastruktúra</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="p-10 md:p-12">
|
||||
<h3 className="text-3xl font-black text-white mb-6 uppercase tracking-tighter font-mono italic group-hover:text-glow transition-all">Kormányzati Szintű Titkosítás</h3>
|
||||
<p className="text-gray-400 mb-10 leading-relaxed">Megoldásaink a legmagasabb szintű állami és katonai sztenderdeknek felelnek meg. Biztonságos adatcsere, védett kommunikációs csatornák és zéró hozzáférésű adattárolás.</p>
|
||||
<button className="flex items-center gap-2 text-cyan-400 font-black text-xs uppercase tracking-[0.3em] hover:text-white transition-colors group/btn hover:text-glow">
|
||||
Részletes specifikáció <ChevronRight className="w-4 h-4 group-hover/btn:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="glass-card rounded-[48px] overflow-hidden group border-cyan-500/10 hover:shadow-[0_0_40px_rgba(34,211,238,0.1)] transition-all">
|
||||
<div className="h-[400px] relative overflow-hidden">
|
||||
<img src="https://images.unsplash.com/photo-1550751827-4bd374c3f58b?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80" alt="Control Room" className="w-full h-full object-cover grayscale opacity-50 group-hover:scale-110 group-hover:opacity-80 transition-all duration-1000" />
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#020205] via-transparent to-transparent"></div>
|
||||
<div className="absolute top-10 right-10 bg-cyan-500 text-black px-4 py-1.5 rounded-full text-[10px] font-black uppercase tracking-widest group-hover:shadow-[0_0_20px_rgba(34,211,238,0.6)] transition-all">Global Monitoring</div>
|
||||
</div>
|
||||
<div className="p-10 md:p-12">
|
||||
<h3 className="text-3xl font-black text-white mb-6 uppercase tracking-tighter font-mono italic group-hover:text-glow transition-all">24/7 AI Felügyeleti Központ</h3>
|
||||
<p className="text-gray-400 mb-10 leading-relaxed">Globális SOC (Security Operations Center) hálózatunk folyamatosan figyeli a gyanús aktivitásokat. Az incidensek kezelése automatizált, az emberi beavatkozás csak validálásra szolgál.</p>
|
||||
<button className="flex items-center gap-2 text-cyan-400 font-black text-xs uppercase tracking-[0.3em] hover:text-white transition-colors group/btn hover:text-glow">
|
||||
Részletes specifikáció <ChevronRight className="w-4 h-4 group-hover/btn:translate-x-1 transition-transform" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* MAP INTEGRATION */}
|
||||
{activeTab === 'home' && (
|
||||
<section className="py-20 bg-[#050505] relative overflow-hidden">
|
||||
<div className="max-w-[1400px] mx-auto px-6">
|
||||
<div className="flex items-center gap-4 mb-10">
|
||||
<MapPin className="text-cyan-500 w-6 h-6" />
|
||||
<h2 className="text-2xl font-mono font-black uppercase tracking-widest">Command Center HQ</h2>
|
||||
</div>
|
||||
<div className="relative w-full h-[500px] rounded-3xl overflow-hidden border border-cyan-900/30 group shadow-[0_0_30px_rgba(0,0,0,0.5)]">
|
||||
<div className="absolute inset-0 z-10 pointer-events-none border-[10px] border-[#020205] opacity-80"></div>
|
||||
<div className="absolute inset-0 z-10 pointer-events-none ring-1 ring-cyan-500/20"></div>
|
||||
<iframe
|
||||
title="Steelguard HQ Map"
|
||||
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2695.565377508381!2d19.0354183769188!3d47.49831737118037!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x4741dc41c2c8f877%3A0x7292275f0a2072e!2sBudapest%2C%20Szent%20Gy%C3%B6rgy%20t%C3%A9r%2C%201014!5e0!3m2!1shu!2shu!4v1716300000000!5m2!1shu!2shu"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0, filter: 'grayscale(1) invert(0.9) contrast(1.2)' }}
|
||||
allowFullScreen
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
></iframe>
|
||||
<div className="absolute top-0 left-0 w-full h-full bg-cyan-500/5 mix-blend-color pointer-events-none"></div>
|
||||
</div>
|
||||
{/* --- HARDWARE PAGE --- */}
|
||||
{activePage === 'hardware' && (
|
||||
<div className="py-24 px-6 max-w-[1400px] mx-auto min-h-screen">
|
||||
<div className="text-center mb-20">
|
||||
<h2 className="text-4xl md:text-7xl font-black text-white uppercase tracking-tighter italic font-mono mb-6 text-glow">Fizikai Biztonság</h2>
|
||||
<p className="text-gray-400 max-w-2xl mx-auto font-medium">Saját fejlesztésű hardvereszközök, melyek a digitális védelmet fizikai réteggel egészítik ki.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
{[
|
||||
{ name: 'S-Core Node', type: 'Hardveres tűzfal', desc: 'Optikai izolációs technológia, 100Gbps átviteli sebesség mellett is észrevehetetlen késleltetés.' },
|
||||
{ name: 'Retina-X', type: 'Biometrikus szkenner', desc: 'Infravörös érhálózat-vizsgálat, melyet lehetetlen másolni vagy kijátszani.' },
|
||||
{ name: 'Vault One', type: 'Kvantum tároló', desc: 'Hardware Security Module (HSM), mely önmegsemmisítő mechanizmussal rendelkezik behatolás esetén.' }
|
||||
].map((h, i) => (
|
||||
<div key={i} className="glass-card p-10 rounded-[40px] flex flex-col items-center text-center group border-cyan-500/5 hover:border-cyan-400/40 transition-all hover:shadow-[0_0_40px_rgba(34,211,238,0.15)]">
|
||||
<div className="w-32 h-32 bg-gray-900 border border-gray-800 rounded-full flex items-center justify-center mb-8 relative group-hover:scale-110 transition-transform">
|
||||
<div className="absolute inset-0 bg-cyan-500/10 rounded-full blur-xl group-hover:bg-cyan-500/30 transition-all"></div>
|
||||
<Chip className="w-16 h-16 text-cyan-400 group-hover:drop-shadow-[0_0_12px_rgba(34,211,238,0.8)] transition-all" />
|
||||
</div>
|
||||
<span className="text-[10px] font-black text-cyan-500 uppercase tracking-widest mb-2 group-hover:text-glow transition-all">{h.type}</span>
|
||||
<h3 className="text-2xl font-black text-white mb-6 uppercase tracking-tighter font-mono group-hover:text-cyan-300 transition-colors">{h.name}</h3>
|
||||
<p className="text-gray-500 text-sm leading-relaxed">{h.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
</main>
|
||||
|
||||
{/* Footer / CTA */}
|
||||
<footer className="py-32 bg-[#020205] relative overflow-hidden">
|
||||
<div className="max-w-[1400px] mx-auto px-6 grid md:grid-cols-4 gap-0 divide-x divide-gray-900 text-center relative z-10 border-y border-gray-900 mb-20">
|
||||
{[
|
||||
{ val: '500+', label: 'NODES ACTIVE' },
|
||||
{ val: '0.01ms', label: 'LATENCY' },
|
||||
{ val: '100%', label: 'UPTIME' },
|
||||
{ val: 'SECURE', label: 'STATUS' }
|
||||
].map((stat, i) => (
|
||||
<div key={i} className="relative py-10 group hover:bg-cyan-900/5 transition-colors cursor-default">
|
||||
<div className="text-5xl font-bold text-gray-700 mb-2 font-mono group-hover:text-cyan-400 group-hover:scale-110 transition-all duration-300 text-glow">{stat.val}</div>
|
||||
<div className="text-cyan-900 text-[10px] font-bold uppercase tracking-[0.3em] group-hover:text-cyan-600">{stat.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Stats & CTA */}
|
||||
<footer className="py-24 relative overflow-hidden bg-transparent">
|
||||
<div className="max-w-[1400px] mx-auto px-6">
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-10 md:gap-0 divide-x divide-gray-900 text-center border-y border-gray-900 py-16 mb-24">
|
||||
{[
|
||||
{ val: '14 PB', label: 'Védett adat' },
|
||||
{ val: '0.00ms', label: 'Esemény válaszidő' },
|
||||
{ val: '256k+', label: 'Napi hárítás' },
|
||||
{ val: 'ZERO', label: 'Biztonsági rés' }
|
||||
].map((s, i) => (
|
||||
<div key={i} className="px-4">
|
||||
<div className="text-3xl md:text-6xl font-black text-white mb-2 font-mono tracking-tighter text-glow italic">{s.val}</div>
|
||||
<div className="text-cyan-900 text-[9px] font-black uppercase tracking-[0.3em]">{s.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="max-w-4xl mx-auto px-6 text-center relative z-10">
|
||||
<div className="inline-block mb-10 p-4 border border-cyan-500/30 rounded-full animate-pulse-glow">
|
||||
<Shield className="w-12 h-12 text-cyan-500" />
|
||||
</div>
|
||||
<h2 className="text-4xl md:text-6xl font-bold text-white mb-8 font-mono uppercase">
|
||||
SECURE YOUR <span className="text-cyan-500">FUTURE</span>
|
||||
</h2>
|
||||
<p className="text-gray-400 mb-12 text-lg max-w-xl mx-auto font-mono text-xs leading-loose">
|
||||
Initiate contact with our security architects. Design a defense strategy leveraging next-gen technologies.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row justify-center gap-6">
|
||||
<button className="cyber-button bg-cyan-600 hover:bg-cyan-500 text-black px-12 py-5 font-bold uppercase tracking-[0.2em] text-xs transition-all shadow-[0_0_20px_rgba(8,145,178,0.5)]">
|
||||
Initialize Sequence
|
||||
</button>
|
||||
<button className="border border-gray-800 hover:border-white text-gray-400 hover:text-white px-12 py-5 font-bold uppercase tracking-[0.2em] text-xs transition-all hover:bg-white/5 hover:shadow-[0_0_15px_rgba(255,255,255,0.2)]">
|
||||
Download Manifest
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-32 pt-10 border-t border-gray-900 text-gray-600 text-[9px] uppercase tracking-[0.2em] flex flex-col md:flex-row justify-between items-center gap-4 font-mono">
|
||||
<div>© 2024 STEELGUARD DEFENSE SYSTEMS.</div>
|
||||
<div className="text-cyan-900">SYSTEM_ID: MW-ENT-8842</div>
|
||||
<div className="max-w-4xl mx-auto text-center space-y-12">
|
||||
<div className="relative inline-block group">
|
||||
<div className="absolute inset-0 bg-cyan-500 blur-3xl opacity-30 animate-pulse group-hover:opacity-60 transition-opacity"></div>
|
||||
<div className="w-20 h-20 md:w-24 md:h-24 bg-gray-900 border border-cyan-500/30 rounded-[32px] flex items-center justify-center relative z-10 mx-auto transform -rotate-12 group-hover:rotate-0 transition-transform duration-500 shadow-[0_0_40px_rgba(34,211,238,0.2)] group-hover:shadow-[0_0_60px_rgba(34,211,238,0.5)] group-hover:border-cyan-400">
|
||||
<ShieldCheck className="w-10 h-10 md:w-12 md:h-12 text-cyan-400 group-hover:drop-shadow-[0_0_8px_rgba(34,211,238,1)]" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 className="text-4xl md:text-7xl font-black text-white uppercase tracking-tighter font-mono leading-none italic text-glow">
|
||||
Ahol a <span className="text-cyan-500 underline decoration-cyan-500/30 underline-offset-8">bizalom</span> <br/>nem kérdés.
|
||||
</h2>
|
||||
|
||||
<p className="text-gray-400 text-lg max-w-xl mx-auto font-medium">
|
||||
Kérje szakértőink konzultációját az Enterprise Security Protocol implementálásához.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row justify-center gap-6 pt-10">
|
||||
<button className="bg-cyan-600 text-black px-12 py-6 font-black uppercase tracking-widest text-sm button-clip hover:bg-white transition-all shadow-[0_0_30px_rgba(34,211,238,0.4)] hover:shadow-[0_0_50px_rgba(34,211,238,0.8)] neon-glow-btn">
|
||||
Szakértői Konzultáció
|
||||
</button>
|
||||
<button className="border border-gray-800 text-gray-500 px-12 py-6 font-black uppercase tracking-widest text-sm button-clip hover:border-cyan-500 hover:text-cyan-400 transition-all hover:shadow-[0_0_20px_rgba(34,211,238,0.2)]">
|
||||
Rendszerbemutató (PDF)
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="pt-32 border-t border-gray-900 flex flex-col md:flex-row justify-between items-center gap-8 text-gray-600 font-mono text-[9px] uppercase tracking-[0.3em]">
|
||||
<div>© 2024 STEELGUARD DEFENSE SYSTEMS. ALL RIGHTS RESERVED.</div>
|
||||
<div className="flex gap-10">
|
||||
<span className="hover:text-cyan-400 cursor-pointer transition-colors hover:text-glow">ADATVÉDELEM</span>
|
||||
<span className="hover:text-cyan-400 cursor-pointer transition-colors hover:text-glow">ÁSZF</span>
|
||||
<span className="text-cyan-900">SYSTEM_ID: CORE-X88-HU</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { ArrowLeft, Instagram, Facebook, MapPin, Phone, Mail, Clock, Heart, Star, ChevronDown } from 'lucide-react';
|
||||
import { ArrowLeft, Instagram, Facebook, MapPin, Phone, Mail, Clock, Heart, Star, ChevronDown, Menu, X } from 'lucide-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const SweetCraving: React.FC = () => {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
@@ -16,9 +17,9 @@ export const SweetCraving: React.FC = () => {
|
||||
return (
|
||||
<div className="font-serif bg-[#FFF5F5] text-[#5D4037] min-h-screen scroll-smooth">
|
||||
{/* Return to Main Site Button */}
|
||||
<div className="fixed bottom-6 right-6 z-[60]">
|
||||
<div className="fixed bottom-4 right-4 md:bottom-6 md:right-6 z-[60]">
|
||||
<Link to="/#references">
|
||||
<button className="bg-white/90 backdrop-blur-md shadow-lg px-5 py-2.5 rounded-full text-sm font-sans font-medium flex items-center hover:bg-white hover:scale-105 transition-all duration-300 group text-[#E91E63]">
|
||||
<button className="bg-white/90 backdrop-blur-md shadow-lg px-4 md:px-5 py-2 md:py-2.5 rounded-full text-xs md:text-sm font-sans font-medium flex items-center hover:bg-white hover:scale-105 transition-all duration-300 group text-[#E91E63]">
|
||||
<ArrowLeft className="w-4 h-4 mr-2 group-hover:-translate-x-1 transition-transform" />
|
||||
Vissza a referenciákhoz
|
||||
</button>
|
||||
@@ -29,15 +30,16 @@ export const SweetCraving: React.FC = () => {
|
||||
<nav
|
||||
className={`fixed top-0 w-full z-40 transition-all duration-500 ${
|
||||
scrolled
|
||||
? 'bg-white/90 backdrop-blur-md shadow-lg py-3'
|
||||
: 'bg-transparent py-6'
|
||||
? 'bg-white/95 backdrop-blur-md shadow-lg py-2 md:py-3'
|
||||
: 'bg-transparent py-4 md:py-6'
|
||||
}`}
|
||||
>
|
||||
<div className="max-w-6xl mx-auto px-6 flex justify-between items-center">
|
||||
<div className={`text-3xl font-bold text-[#E91E63] italic transition-all duration-300 ${scrolled ? 'scale-90' : 'scale-100'}`}>
|
||||
<div className="max-w-6xl mx-auto px-4 md:px-6 flex justify-between items-center">
|
||||
<div className={`text-2xl md:text-3xl font-bold text-[#E91E63] italic transition-all duration-300 ${scrolled ? 'scale-90' : 'scale-100'}`}>
|
||||
SweetCraving
|
||||
</div>
|
||||
<div className="hidden md:flex space-x-10 font-medium font-sans text-sm tracking-wide">
|
||||
|
||||
<div className="hidden md:flex space-x-8 lg:space-x-10 font-medium font-sans text-sm tracking-wide">
|
||||
{['Kezdőlap', 'Rólunk', 'Kínálat', 'Vélemények'].map((item, i) => (
|
||||
<a
|
||||
key={i}
|
||||
@@ -49,10 +51,33 @@ export const SweetCraving: React.FC = () => {
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
<button className="bg-[#E91E63] text-white px-8 py-2.5 rounded-full font-sans font-bold text-sm hover:bg-[#D81B60] transition-all shadow-lg hover:shadow-[#E91E63]/30 hover:-translate-y-0.5 transform">
|
||||
Rendelés
|
||||
</button>
|
||||
|
||||
<div className="flex items-center gap-4">
|
||||
<button className="hidden sm:block bg-[#E91E63] text-white px-6 md:px-8 py-2 md:2.5 rounded-full font-sans font-bold text-xs md:text-sm hover:bg-[#D81B60] transition-all shadow-lg hover:shadow-[#E91E63]/30">
|
||||
Rendelés
|
||||
</button>
|
||||
<button onClick={() => setMobileMenuOpen(!mobileMenuOpen)} className="md:hidden p-2 text-[#E91E63]">
|
||||
{mobileMenuOpen ? <X /> : <Menu />}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile Nav Overlay */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="md:hidden absolute top-full left-0 w-full bg-white shadow-2xl animate-fade-in p-6 space-y-6 flex flex-col font-sans font-bold text-center border-t border-gray-100">
|
||||
{['Kezdőlap', 'Rólunk', 'Kínálat', 'Vélemények'].map((item, i) => (
|
||||
<a
|
||||
key={i}
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
href={`#${item.toLowerCase() === 'kezdőlap' ? 'home' : item === 'Kínálat' ? 'menu' : item === 'Rólunk' ? 'about' : 'contact'}`}
|
||||
className="text-lg hover:text-[#E91E63]"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
))}
|
||||
<button className="bg-[#E91E63] text-white py-4 rounded-xl">Rendelés Most</button>
|
||||
</div>
|
||||
)}
|
||||
</nav>
|
||||
|
||||
{/* Hero Section */}
|
||||
@@ -61,86 +86,84 @@ export const SweetCraving: React.FC = () => {
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1558961363-fa8fdf82db35?auto=format&fit=crop&w=1920&q=80"
|
||||
alt="Desszertműhely Hero"
|
||||
className="w-full h-full object-cover"
|
||||
className="w-full h-full object-cover object-center"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#FFF5F5] via-white/20 to-transparent"></div>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#FFF5F5] via-white/40 to-transparent md:via-white/20"></div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 text-center px-4 max-w-4xl mx-auto mt-16">
|
||||
<div className="relative z-10 text-center px-4 max-w-4xl mx-auto pt-20">
|
||||
<div className="animate-fade-in-up" style={{ animationDelay: '0.1s' }}>
|
||||
<span className="bg-white/80 backdrop-blur-md px-6 py-2 rounded-full text-[#E91E63] text-xs font-bold font-sans tracking-[0.2em] uppercase mb-8 inline-block shadow-sm">
|
||||
<span className="bg-white/80 backdrop-blur-md px-4 md:px-6 py-1.5 md:py-2 rounded-full text-[#E91E63] text-[10px] md:text-xs font-bold font-sans tracking-[0.2em] uppercase mb-6 md:mb-8 inline-block shadow-sm">
|
||||
Kézműves Desszertműhely
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-6xl md:text-8xl font-bold mb-8 drop-shadow-sm text-gray-900 leading-tight animate-fade-in-up" style={{ animationDelay: '0.3s' }}>
|
||||
Édes Álmok <br/>
|
||||
<h1 className="text-4xl sm:text-6xl md:text-8xl font-bold mb-6 md:mb-8 drop-shadow-sm text-gray-900 leading-tight animate-fade-in-up px-2" style={{ animationDelay: '0.3s' }}>
|
||||
Édes Álmok <br className="hidden sm:block" />
|
||||
<span className="text-transparent bg-clip-text bg-gradient-to-r from-[#E91E63] to-[#FF80AB]">
|
||||
Süteménybe Zárva
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<p className="text-xl md:text-2xl text-gray-800/80 max-w-2xl mx-auto mb-12 font-medium leading-relaxed animate-fade-in-up" style={{ animationDelay: '0.5s' }}>
|
||||
<p className="text-base md:text-xl lg:text-2xl text-gray-800/80 max-w-2xl mx-auto mb-8 md:mb-12 font-medium leading-relaxed animate-fade-in-up px-4" style={{ animationDelay: '0.5s' }}>
|
||||
Természetes alapanyagokból, szívvel-lélekkel készült desszertek minden alkalomra.
|
||||
<br className="hidden md:block"/> Mert minden nap megérdemel egy kis kényeztetést.
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-5 justify-center animate-fade-in-up" style={{ animationDelay: '0.7s' }}>
|
||||
<a href="#menu" className="bg-[#E91E63] text-white px-10 py-4 rounded-full font-sans font-bold hover:bg-[#D81B60] transition-all shadow-xl shadow-[#E91E63]/30 hover:-translate-y-1 hover:scale-105">
|
||||
Kínálatunk Megtekintése
|
||||
<div className="flex flex-col sm:flex-row gap-4 md:gap-5 justify-center animate-fade-in-up px-6 sm:px-0" style={{ animationDelay: '0.7s' }}>
|
||||
<a href="#menu" className="bg-[#E91E63] text-white px-8 md:px-10 py-3 md:py-4 rounded-full font-sans font-bold hover:bg-[#D81B60] transition-all shadow-xl shadow-[#E91E63]/30 hover:-translate-y-1">
|
||||
Kínálatunk
|
||||
</a>
|
||||
<a href="#about" className="bg-white text-[#5D4037] px-10 py-4 rounded-full font-sans font-bold hover:bg-gray-50 transition-all shadow-lg hover:-translate-y-1 hover:scale-105">
|
||||
<a href="#about" className="bg-white text-[#5D4037] px-8 md:px-10 py-3 md:py-4 rounded-full font-sans font-bold hover:bg-gray-50 transition-all shadow-lg hover:-translate-y-1">
|
||||
Ismerj meg minket
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Scroll Indicator */}
|
||||
<div className="absolute bottom-10 left-1/2 transform -translate-x-1/2 animate-bounce">
|
||||
<ChevronDown className="w-8 h-8 text-[#E91E63] opacity-60" />
|
||||
<div className="absolute bottom-6 md:bottom-10 left-1/2 transform -translate-x-1/2 animate-bounce">
|
||||
<ChevronDown className="w-6 h-6 md:w-8 h-8 text-[#E91E63] opacity-60" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* About Section */}
|
||||
<section id="about" className="py-32 px-6 bg-white overflow-hidden">
|
||||
<section id="about" className="py-20 md:py-32 px-4 md:px-6 bg-white overflow-hidden">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="grid md:grid-cols-2 gap-20 items-center">
|
||||
<div className="relative group">
|
||||
<div className="absolute -top-6 -left-6 w-full h-full border-4 border-[#FF80AB]/30 rounded-[2rem] transition-transform duration-500 group-hover:translate-x-2 group-hover:translate-y-2"></div>
|
||||
<div className="grid md:grid-cols-2 gap-12 md:gap-20 items-center">
|
||||
<div className="relative group px-4 md:px-0">
|
||||
<div className="absolute -top-4 md:-top-6 -left-4 md:-left-6 w-full h-full border-4 border-[#FF80AB]/30 rounded-[1.5rem] md:rounded-[2rem]"></div>
|
||||
<img
|
||||
src="https://images.unsplash.com/photo-1556910103-1c02745aae4d?auto=format&fit=crop&w=1000&q=80"
|
||||
alt="Pék és Cukrászmunka"
|
||||
className="rounded-[2rem] shadow-2xl relative z-10 transform transition-transform duration-700 hover:scale-[1.02]"
|
||||
className="rounded-[1.5rem] md:rounded-[2rem] shadow-2xl relative z-10 w-full"
|
||||
/>
|
||||
{/* Floating Badge */}
|
||||
<div className="absolute -bottom-10 -right-10 z-20 bg-white p-6 rounded-2xl shadow-xl animate-bounce-slow hidden lg:block">
|
||||
{/* Floating Badge (hidden on small mobile) */}
|
||||
<div className="absolute -bottom-6 -right-6 md:-bottom-10 md:-right-10 z-20 bg-white p-4 md:p-6 rounded-xl md:rounded-2xl shadow-xl animate-bounce-slow hidden sm:block">
|
||||
<div className="text-center">
|
||||
<p className="text-4xl font-bold text-[#E91E63]">5+</p>
|
||||
<p className="text-sm font-sans text-gray-500 uppercase tracking-wider">Év Tapasztalat</p>
|
||||
<p className="text-2xl md:text-4xl font-bold text-[#E91E63]">5+</p>
|
||||
<p className="text-[10px] md:text-sm font-sans text-gray-500 uppercase tracking-wider">Év Tapasztalat</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-8">
|
||||
<h2 className="text-5xl font-bold text-[#5D4037] leading-tight">
|
||||
<div className="space-y-6 md:space-y-8 text-center md:text-left px-2">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-[#5D4037] leading-tight">
|
||||
A szenvedélyünk <br/>
|
||||
<span className="text-[#E91E63] italic">a minőség</span>
|
||||
<span className="text-[#E91E63] italic text-3xl md:text-4xl lg:text-5xl">a minőség</span>
|
||||
</h2>
|
||||
<p className="text-lg leading-relaxed text-[#795548] font-sans">
|
||||
2018 óta készítjük desszertjeinket Budapest szívében. Hiszünk abban, hogy egy sütemény nemcsak étel, hanem élmény. Ezért kizárólag prémium belga csokoládét, termelői tejet és friss gyümölcsöket használunk.
|
||||
<p className="text-base md:text-lg leading-relaxed text-[#795548] font-sans">
|
||||
2018 óta készítjük desszertjeinket Budapest szívében. Hiszünk abban, hogy egy sütemény nemcsak étel, hanem élmény.
|
||||
</p>
|
||||
|
||||
<div className="grid gap-6">
|
||||
<div className="grid gap-4 md:gap-6">
|
||||
{[
|
||||
{ text: '100% Természetes alapanyagok', icon: Heart },
|
||||
{ text: 'Glutén- és laktózmentes opciók', icon: Star },
|
||||
{ text: 'Egyedi tortarendelés 48 órán belül', icon: Clock }
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex items-center gap-4 p-4 rounded-xl bg-[#FFF5F5] border border-[#FF80AB]/20 transition-all hover:shadow-md hover:bg-[#fff0f0]">
|
||||
<div className="w-10 h-10 rounded-full bg-white flex items-center justify-center text-[#E91E63] shadow-sm">
|
||||
<item.icon className="w-5 h-5" />
|
||||
<div key={i} className="flex items-center gap-4 p-3 md:p-4 rounded-xl bg-[#FFF5F5] border border-[#FF80AB]/20 transition-all">
|
||||
<div className="w-8 h-8 md:w-10 md:h-10 rounded-full bg-white flex items-center justify-center text-[#E91E63] shadow-sm flex-shrink-0">
|
||||
<item.icon className="w-4 h-4 md:w-5 h-5" />
|
||||
</div>
|
||||
<span className="font-bold text-[#5D4037]">{item.text}</span>
|
||||
<span className="font-bold text-[#5D4037] text-sm md:text-base">{item.text}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -150,16 +173,16 @@ export const SweetCraving: React.FC = () => {
|
||||
</section>
|
||||
|
||||
{/* Menu Grid */}
|
||||
<section id="menu" className="py-32 bg-[#FFF5F5]">
|
||||
<div className="max-w-6xl mx-auto px-6">
|
||||
<div className="text-center mb-20">
|
||||
<h2 className="text-5xl font-bold mb-6 text-[#5D4037]">Legnépszerűbb Finomságok</h2>
|
||||
<p className="text-[#795548] text-xl max-w-2xl mx-auto font-sans">
|
||||
<section id="menu" className="py-20 md:py-32 bg-[#FFF5F5]">
|
||||
<div className="max-w-6xl mx-auto px-4 md:px-6">
|
||||
<div className="text-center mb-12 md:mb-20">
|
||||
<h2 className="text-4xl md:text-5xl font-bold mb-4 md:mb-6 text-[#5D4037]">Kínálatunk</h2>
|
||||
<p className="text-[#795548] text-base md:text-xl max-w-2xl mx-auto font-sans px-4">
|
||||
Válogasson kedvenc süteményeink közül, melyeket minden reggel frissen készítünk.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-10">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6 md:gap-10">
|
||||
{[
|
||||
{ title: 'Macaron Válogatás', price: '3 490 Ft', img: 'https://images.unsplash.com/photo-1569864358642-9d1684040f43?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80', tag: 'Best Seller' },
|
||||
{ title: 'Epres Sajttorta', price: '1 290 Ft', img: 'https://images.unsplash.com/photo-1533134242443-d4fd215305ad?auto=format&fit=crop&w=800&q=80', tag: null },
|
||||
@@ -168,96 +191,87 @@ export const SweetCraving: React.FC = () => {
|
||||
{ title: 'Cupcake Mix', price: '2 990 Ft', img: 'https://images.unsplash.com/photo-1519869325930-281384150729?auto=format&fit=crop&w=800&q=80', tag: null },
|
||||
{ title: 'Vajas Croissant', price: '890 Ft', img: 'https://images.unsplash.com/photo-1509440159596-0249088772ff?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80', tag: 'Friss' }
|
||||
].map((item, i) => (
|
||||
<div key={i} className="group bg-white rounded-3xl p-4 shadow-md hover:shadow-2xl transition-all duration-500 hover:-translate-y-2">
|
||||
<div className="overflow-hidden rounded-2xl mb-6 h-64 relative">
|
||||
<div key={i} className="group bg-white rounded-3xl p-4 shadow-md hover:shadow-2xl transition-all duration-500">
|
||||
<div className="overflow-hidden rounded-2xl mb-4 md:mb-6 h-48 md:h-64 relative">
|
||||
<img
|
||||
src={item.img}
|
||||
alt={item.title}
|
||||
className="w-full h-full object-cover transform group-hover:scale-110 transition-transform duration-700"
|
||||
/>
|
||||
{item.tag && (
|
||||
<div className="absolute top-4 left-4 bg-white/90 backdrop-blur px-3 py-1 rounded-full text-xs font-bold text-[#E91E63] uppercase tracking-wider shadow-sm">
|
||||
<div className="absolute top-4 left-4 bg-white/90 backdrop-blur px-3 py-1 rounded-full text-[10px] font-bold text-[#E91E63] uppercase tracking-wider">
|
||||
{item.tag}
|
||||
</div>
|
||||
)}
|
||||
{/* Quick Add Overlay */}
|
||||
<div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center">
|
||||
<button className="bg-white text-[#E91E63] px-6 py-2 rounded-full font-bold transform translate-y-4 group-hover:translate-y-0 transition-transform duration-300">
|
||||
Kosárba
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="px-2 pb-2">
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<h3 className="text-2xl font-bold text-[#5D4037] group-hover:text-[#E91E63] transition-colors">{item.title}</h3>
|
||||
<span className="text-lg font-bold text-[#E91E63] bg-[#FFF5F5] px-3 py-1 rounded-lg">{item.price}</span>
|
||||
<div className="px-2 pb-2 text-center sm:text-left">
|
||||
<div className="flex flex-col sm:flex-row justify-between items-center sm:items-start mb-2 gap-2">
|
||||
<h3 className="text-xl md:text-2xl font-bold text-[#5D4037]">{item.title}</h3>
|
||||
<span className="text-base md:text-lg font-bold text-[#E91E63] bg-[#FFF5F5] px-3 py-0.5 rounded-lg">{item.price}</span>
|
||||
</div>
|
||||
<p className="text-gray-500 text-sm line-clamp-2">Krémes, ízletes finomság, amely elolvad a szádban.</p>
|
||||
<p className="text-gray-500 text-xs md:text-sm line-clamp-2">Krémes, ízletes finomság, amely elolvad a szádban.</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="mt-16 text-center">
|
||||
<button className="border-2 border-[#E91E63] text-[#E91E63] px-10 py-3 rounded-full font-bold hover:bg-[#E91E63] hover:text-white transition-all duration-300 uppercase tracking-wider text-sm">
|
||||
<div className="mt-12 md:mt-16 text-center">
|
||||
<button className="border-2 border-[#E91E63] text-[#E91E63] px-8 md:px-10 py-3 rounded-full font-bold hover:bg-[#E91E63] hover:text-white transition-all uppercase tracking-wider text-xs md:text-sm">
|
||||
Teljes étlap letöltése
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Testimonials (Simple) */}
|
||||
<section className="py-24 bg-white">
|
||||
<div className="max-w-4xl mx-auto px-6 text-center">
|
||||
<Star className="w-10 h-10 text-yellow-400 fill-current mx-auto mb-6" />
|
||||
<h2 className="text-4xl font-bold mb-8 text-[#5D4037]">Vendégeink mondták</h2>
|
||||
<blockquote className="text-2xl italic text-gray-600 font-serif leading-relaxed mb-8">
|
||||
"A legfinomabb macaron, amit valaha ettem! A pisztáciás egyszerűen mennyei. Mindenkinek csak ajánlani tudom a helyet, igazi ékszerdoboz."
|
||||
{/* Testimonials */}
|
||||
<section className="py-20 md:py-24 bg-white px-4">
|
||||
<div className="max-w-4xl mx-auto text-center">
|
||||
<Star className="w-8 h-8 md:w-10 md:h-10 text-yellow-400 fill-current mx-auto mb-6" />
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-6 md:mb-8 text-[#5D4037]">Vendégeink mondták</h2>
|
||||
<blockquote className="text-lg md:text-2xl italic text-gray-600 font-serif leading-relaxed mb-6 md:mb-8 px-4">
|
||||
"A legfinomabb macaron, amit valaha ettem! A pisztáciás egyszerűen mennyei. Mindenkinek csak ajánlani tudom."
|
||||
</blockquote>
|
||||
<cite className="font-bold text-[#E91E63] not-italic">— Kovács Anna, Budapest</cite>
|
||||
<cite className="font-bold text-[#E91E63] not-italic text-sm md:text-base">— Kovács Anna, Budapest</cite>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Contact & Footer */}
|
||||
<section id="contact" className="bg-[#5D4037] text-white py-24 px-6 relative overflow-hidden">
|
||||
{/* Background Pattern */}
|
||||
<div className="absolute inset-0 opacity-5" style={{backgroundImage: 'radial-gradient(circle, #ffffff 2px, transparent 2px)', backgroundSize: '30px 30px'}}></div>
|
||||
|
||||
<section id="contact" className="bg-[#5D4037] text-white py-20 md:py-24 px-4 md:px-6 relative overflow-hidden">
|
||||
<div className="max-w-4xl mx-auto text-center relative z-10">
|
||||
<h2 className="text-4xl font-bold mb-16">Látogass el hozzánk</h2>
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-12 md:mb-16">Látogass el hozzánk</h2>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-12 mb-16">
|
||||
<div className="flex flex-col items-center group">
|
||||
<div className="w-16 h-16 bg-white/10 rounded-full flex items-center justify-center mb-6 group-hover:bg-[#E91E63] transition-colors duration-300">
|
||||
<MapPin className="w-8 h-8" />
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-10 md:gap-12 mb-12 md:mb-16">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="w-12 h-12 md:w-16 md:h-16 bg-white/10 rounded-full flex items-center justify-center mb-4 md:mb-6">
|
||||
<MapPin className="w-6 h-6 md:w-8 h-8" />
|
||||
</div>
|
||||
<h4 className="font-bold text-xl mb-3">Címünk</h4>
|
||||
<p className="text-white/70 leading-relaxed">1052 Budapest,<br/>Petőfi Sándor utca 12.</p>
|
||||
<h4 className="font-bold text-lg md:text-xl mb-2 md:mb-3">Címünk</h4>
|
||||
<p className="text-white/70 text-sm md:text-base leading-relaxed">1052 Budapest,<br/>Petőfi Sándor utca 12.</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center group">
|
||||
<div className="w-16 h-16 bg-white/10 rounded-full flex items-center justify-center mb-6 group-hover:bg-[#E91E63] transition-colors duration-300">
|
||||
<Clock className="w-8 h-8" />
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="w-12 h-12 md:w-16 md:h-16 bg-white/10 rounded-full flex items-center justify-center mb-4 md:mb-6">
|
||||
<Clock className="w-6 h-6 md:w-8 h-8" />
|
||||
</div>
|
||||
<h4 className="font-bold text-xl mb-3">Nyitvatartás</h4>
|
||||
<p className="text-white/70 leading-relaxed">H-P: 08:00 - 19:00<br/>Szo-V: 09:00 - 16:00</p>
|
||||
<h4 className="font-bold text-lg md:text-xl mb-2 md:mb-3">Nyitvatartás</h4>
|
||||
<p className="text-white/70 text-sm md:text-base leading-relaxed">H-P: 08:00 - 19:00<br/>Szo-V: 09:00 - 16:00</p>
|
||||
</div>
|
||||
<div className="flex flex-col items-center group">
|
||||
<div className="w-16 h-16 bg-white/10 rounded-full flex items-center justify-center mb-6 group-hover:bg-[#E91E63] transition-colors duration-300">
|
||||
<Phone className="w-8 h-8" />
|
||||
<div className="flex flex-col items-center sm:col-span-2 md:col-span-1">
|
||||
<div className="w-12 h-12 md:w-16 md:h-16 bg-white/10 rounded-full flex items-center justify-center mb-4 md:mb-6">
|
||||
<Phone className="w-6 h-6 md:w-8 h-8" />
|
||||
</div>
|
||||
<h4 className="font-bold text-xl mb-3">Kapcsolat</h4>
|
||||
<p className="text-white/70 leading-relaxed">+36 1 234 5678<br/>hello@sweetcraving.hu</p>
|
||||
<h4 className="font-bold text-lg md:text-xl mb-2 md:mb-3">Kapcsolat</h4>
|
||||
<p className="text-white/70 text-sm md:text-base leading-relaxed">+36 1 234 5678<br/>hello@sweetcraving.hu</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center space-x-8">
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all transform hover:scale-110"><Facebook className="w-8 h-8" /></a>
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all transform hover:scale-110"><Instagram className="w-8 h-8" /></a>
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all transform hover:scale-110"><Mail className="w-8 h-8" /></a>
|
||||
<div className="flex justify-center space-x-6 md:space-x-8">
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all"><Facebook className="w-6 h-6 md:w-8 h-8" /></a>
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all"><Instagram className="w-6 h-6 md:w-8 h-8" /></a>
|
||||
<a href="#" className="opacity-60 hover:opacity-100 hover:text-[#E91E63] transition-all"><Mail className="w-6 h-6 md:w-8 h-8" /></a>
|
||||
</div>
|
||||
|
||||
<div className="mt-16 pt-8 border-t border-white/10 text-white/40 text-sm font-sans">
|
||||
© 2024 SweetCraving. Ez egy demonstrációs weboldal a MotionWeb referenciáihoz.
|
||||
<div className="mt-12 md:mt-16 pt-8 border-t border-white/10 text-white/40 text-[10px] md:text-xs font-sans">
|
||||
© 2024 SweetCraving. Demonstrációs oldal.
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
104
supabase/functions/check-subscriptions/index.ts
Normal file
104
supabase/functions/check-subscriptions/index.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
|
||||
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.39.3'
|
||||
|
||||
declare const Deno: any;
|
||||
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
||||
}
|
||||
|
||||
Deno.serve(async (req: any) => {
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders })
|
||||
}
|
||||
|
||||
try {
|
||||
const supabase = createClient(
|
||||
Deno.env.get('SUPABASE_URL') ?? '',
|
||||
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY') ?? ''
|
||||
)
|
||||
|
||||
// Fetch active subscriptions
|
||||
const { data: subscriptions, error } = await supabase
|
||||
.from('maintenance_subscriptions')
|
||||
.select('*, order:orders(*)')
|
||||
.eq('status', 'active');
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
const notificationsToSend: any[] = [];
|
||||
const today = new Date();
|
||||
|
||||
// Mock email sending function for now
|
||||
const sendEmailMock = async (payload: any) => {
|
||||
console.log("Mock email sent:", payload);
|
||||
// In production, you would invoke the 'resend' function here
|
||||
};
|
||||
|
||||
if (subscriptions) {
|
||||
for (const sub of subscriptions) {
|
||||
const billingDate = new Date(sub.next_billing_date);
|
||||
const daysUntil = Math.ceil((billingDate.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));
|
||||
|
||||
// Logic: Notify if <= 30 days and not notified recently (e.g. in last 14 days)
|
||||
let shouldNotify = false;
|
||||
|
||||
// If it's already overdue or coming up in 30 days
|
||||
if (daysUntil <= 30) {
|
||||
if (!sub.last_notified_at) {
|
||||
shouldNotify = true;
|
||||
} else {
|
||||
const lastNotified = new Date(sub.last_notified_at);
|
||||
const daysSinceLastNotification = Math.ceil((today.getTime() - lastNotified.getTime()) / (1000 * 60 * 60 * 24));
|
||||
// Only notify if 2 weeks passed since last notification
|
||||
if (daysSinceLastNotification > 14) {
|
||||
shouldNotify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldNotify) {
|
||||
const payload = {
|
||||
to: sub.client_email,
|
||||
subject: `Emlékeztető: Éves díj esedékes (${daysUntil} nap)`,
|
||||
daysLeft: daysUntil,
|
||||
domain: sub.order?.details?.domainName || 'Weboldal',
|
||||
subscriptionId: sub.id
|
||||
};
|
||||
|
||||
notificationsToSend.push(payload);
|
||||
|
||||
// Itt hívnánk meg a sendEmail függvényt
|
||||
await sendEmailMock(payload);
|
||||
|
||||
// Update last_notified_at to keep data consistent
|
||||
const { error: updateError } = await supabase
|
||||
.from('maintenance_subscriptions')
|
||||
.update({ last_notified_at: new Date().toISOString() })
|
||||
.eq('id', sub.id);
|
||||
|
||||
if (updateError) {
|
||||
console.error(`Failed to update subscription ${sub.id}:`, updateError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({ success: true, notifications: notificationsToSend }),
|
||||
{
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 200,
|
||||
}
|
||||
)
|
||||
} catch (err: any) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: err.message }),
|
||||
{
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 400,
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
90
supabase/functions/create-checkout-session/index.ts
Normal file
90
supabase/functions/create-checkout-session/index.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
// @ts-nocheck
|
||||
import { serve } from "https://deno.land/std@0.168.0/http/server.ts"
|
||||
import { Stripe } from "https://esm.sh/stripe@12.0.0?target=deno"
|
||||
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
|
||||
}
|
||||
|
||||
serve(async (req) => {
|
||||
if (req.method === 'OPTIONS') {
|
||||
return new Response('ok', { headers: corsHeaders })
|
||||
}
|
||||
|
||||
try {
|
||||
const STRIPE_SECRET_KEY = Deno.env.get('STRIPE_SECRET_KEY')
|
||||
if (!STRIPE_SECRET_KEY) {
|
||||
throw new Error('STRIPE_SECRET_KEY not set in environment variables')
|
||||
}
|
||||
|
||||
const stripe = new Stripe(STRIPE_SECRET_KEY, {
|
||||
apiVersion: '2022-11-15',
|
||||
httpClient: Stripe.createFetchHttpClient(),
|
||||
})
|
||||
|
||||
const { order_id, package_name, payment_type, customer_email } = await req.json()
|
||||
|
||||
// Árazási logika (HUF-ban)
|
||||
let priceAmount = 0
|
||||
|
||||
// Landing Page: 190.000 Ft (Előleg: 40.000, Vég: 150.000)
|
||||
if (package_name === 'Landing Page') {
|
||||
if (payment_type === 'deposit') priceAmount = 40000;
|
||||
else if (payment_type === 'final') priceAmount = 150000;
|
||||
}
|
||||
// Pro Web: 350.000 Ft (Előleg: 80.000, Vég: 270.000)
|
||||
else if (package_name === 'Pro Web') {
|
||||
if (payment_type === 'deposit') priceAmount = 80000;
|
||||
else if (payment_type === 'final') priceAmount = 270000;
|
||||
}
|
||||
|
||||
if (priceAmount === 0) {
|
||||
throw new Error('Invalid package or payment type')
|
||||
}
|
||||
|
||||
// Origin meghatározása a visszairányításhoz
|
||||
const origin = req.headers.get('origin') || 'https://motionweb.hu'
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
payment_method_types: ['card'],
|
||||
line_items: [
|
||||
{
|
||||
price_data: {
|
||||
currency: 'huf',
|
||||
product_data: {
|
||||
name: `${package_name} - ${payment_type === 'deposit' ? 'Előleg' : 'Fennmaradó összeg'}`,
|
||||
},
|
||||
unit_amount: priceAmount * 100, // Fillérben kell megadni
|
||||
},
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
mode: 'payment',
|
||||
success_url: `${origin}/#/dashboard?payment_success=true&order_id=${order_id}`,
|
||||
cancel_url: `${origin}/#/dashboard?payment_cancelled=true&order_id=${order_id}`,
|
||||
customer_email: customer_email,
|
||||
metadata: {
|
||||
order_id: order_id,
|
||||
payment_type: payment_type
|
||||
},
|
||||
})
|
||||
|
||||
return new Response(
|
||||
JSON.stringify({ url: session.url }),
|
||||
{
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 200,
|
||||
}
|
||||
)
|
||||
} catch (error: any) {
|
||||
console.error(error)
|
||||
return new Response(
|
||||
JSON.stringify({ error: error.message }),
|
||||
{
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' },
|
||||
status: 400,
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
19
types.ts
19
types.ts
@@ -9,11 +9,14 @@ export interface Service {
|
||||
export interface ProductPackage {
|
||||
id: string;
|
||||
name: string;
|
||||
price: string;
|
||||
desc: string; // Description
|
||||
price: string; // Megjelenített ár szöveg (pl. "150.000 Ft" vagy "Egyedi árazás")
|
||||
total_price?: number; // Numerikus teljes ár
|
||||
advance_price?: number; // Numerikus előleg
|
||||
is_custom_price?: boolean; // Egyedi árazás jelző
|
||||
desc: string;
|
||||
features: string[];
|
||||
isPopular?: boolean;
|
||||
cta: string; // Call to Action button text
|
||||
cta: string;
|
||||
}
|
||||
|
||||
export interface Reference {
|
||||
@@ -42,3 +45,13 @@ export interface Invoice {
|
||||
status: 'paid' | 'pending' | 'overdue';
|
||||
pdf_url?: string;
|
||||
}
|
||||
|
||||
export interface MaintenanceSubscription {
|
||||
id: string;
|
||||
order_id: string;
|
||||
client_email: string;
|
||||
start_date: string;
|
||||
next_billing_date: string;
|
||||
status: 'active' | 'overdue' | 'cancelled';
|
||||
last_notified_at?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user