357 lines
27 KiB
React
357 lines
27 KiB
React
import React, { useEffect, useRef, useState } from 'react';
|
||
import {
|
||
ArrowRight, Bell, Building2, CalendarDays, ChartNoAxesCombined, CheckCircle2,
|
||
FileSearch, Gavel, Kanban, MapPin, Radar, Sparkles, Tag, Timer, TrendingUp, Zap,
|
||
Microscope, FileSignature, Package, Search, Calculator, Trophy, Send, FolderCheck, ScanText, BookOpen, Smartphone, Plug, CalendarClock, MessageSquareText, FolderSearch, ShieldAlert } from 'lucide-react';
|
||
|
||
/* ---------- yeni eklenenler ---------- */
|
||
|
||
const YENILIKLER = [
|
||
{ icon: MessageSquareText, baslik: 'Teklif Asistanı: belgeye sor, taslağı denetle, taslak üret', metin: 'Detaydaki yeni sekme: dokümana “teminat ne kadar?” diye sorun ([n] atıflı yanıt), teklif metninizi gerekliliklerle denetleyin (karşılanıyor / eksik / belirsiz), kapak-teknik-ticari taslağı üretin; rakam uydurmaz.' },
|
||
{ icon: FolderSearch, baslik: 'Yeterlilik eşleştirme', metin: 'Derin analizin belge kontrol listesindeki her madde Doküman Deposu’ndaki evrakla eşlenir: Depoda hazır / Yakında dolacak / Süresi dolmuş / Depoda yok.' },
|
||
{ icon: Plug, baslik: 'MCP sunucusu + RSS', metin: 'Claude Code, Cursor ve Claude Desktop’tan İhaleist’i doğrudan sorgulayın (ihale ara, sonuç ara, kalem ara, yaklaşan tarihler); filtreli RSS beslemesini okuyucunuza veya Slack’e ekleyin.' },
|
||
{ icon: CalendarClock, baslik: 'Yaklaşan ihale tarihleri + haftalık brief', metin: 'Sağ panelde takipli ihalelerin 14 günlük geri sayımı; her Pazartesi 08:00 bu hafta yapılacaklar ve geçen hafta sonuçlananlar Telegram + e-postayla tek mesajda.' },
|
||
{ icon: ShieldAlert, baslik: '5 yeni kırmızı bayrak kuralı', metin: 'Kısa süre, hafta sonu tarih, geç sözleşme, kazananı gizli ve doğrudan temin parçalama şüphesi (aynı idare + sektörde 30 günde 3+ DT) mevcut kurallara eklendi.' },
|
||
{ icon: FileSignature, baslik: 'İhale dosyası hazırla', metin: 'Analizden sonra teklif mektubu, birim fiyat cetveli ve evrak listesi tek tıkla; eksik bilgiyi sorar, yazıyla tutarı kendisi yazar, yazdırmaya hazır çıkarır.' },
|
||
{ icon: Package, baslik: 'Kartta teklif cetveli kalemleri', metin: 'Şartname indirmeden kalem adı, miktar ve birim ihale kartında. Ortak havuz: bir kullanıcının yüklediği doküman herkesin kartını doldurur.' },
|
||
{ icon: Search, baslik: 'Ürün arama — cetvel ve şartname içinde', metin: 'Ürününüzün adıyla EKAP teklif cetveli ve teknik şartnamelerin içinde arayın; OKAS koduyla da tarayın. Başlıkta geçmeyen ihaleleri bulun.' },
|
||
{ icon: Sparkles, baslik: 'Uyum skoru ve firma eşiği', metin: 'Firma profilinize göre her ihaleye hibrit (sözcük + anlamsal) uyum puanı; eşiğinizi kaydırın, yalnızca size uyanları görün, “Şirketime en uyumlu” sıralayın.' },
|
||
{ icon: Calculator, baslik: 'Sınır değer hesaplayıcı', metin: 'Kamu İhale Genel Tebliği 2026 formülleriyle hizmet, personel dayalı, mal ve yapım işleri için sınır değer; aşırı düşük sorgusuna kimin gireceğini önceden görün.' },
|
||
{ icon: Trophy, baslik: 'Kazanan istihbaratı', metin: 'Rakip firmanın kazandığı ihaleler, ortalama teklif, kırım oranı ve tek teklif oranı — kısmi ihale tuzağı ayıklanmış olarak.' },
|
||
{ icon: Send, baslik: 'Zeyilname, sonuç ve Telegram', metin: 'Takipteki ihalede zeyilname/tarih değişimi ve sonuç açıklanınca uygulama içi bildirim, e-posta ve isterseniz Telegram. Kurulum kılavuzu içeride.' },
|
||
{ icon: FolderCheck, baslik: 'Belge deposu süre takibi', metin: 'İmza sirküleri, ISO, yetki belgesi… toplu yükleyin, kategori ve son geçerlilik girin; süresi dolmadan 30 gün önce uyarı gelir.' },
|
||
{ icon: ScanText, baslik: 'Taranmış PDF için OCR', metin: 'Metin katmanı olmayan taranmış şartnameler tarayıcıda Türkçe OCR ile okunur; analiz ve kalem çıkarımı bunlarda da çalışır.' },
|
||
{ icon: BookOpen, baslik: 'Her ekranda kullanım kılavuzu', metin: 'Sağ alttaki “?” ya da klavyeden ? — bulunduğunuz ekrana özel adım adım kılavuz yan panelde açılır.' },
|
||
{ icon: Smartphone, baslik: 'Mobil uyumlu PWA', metin: 'Telefon ana ekranına ekleyin; filtreler çekmecede, kartlar tek sütunda. Bildirimler ve çevrimdışı kabukla cebinizde.' },
|
||
];
|
||
|
||
/* ---------- yardımcılar ---------- */
|
||
|
||
const useReveal = () => {
|
||
useEffect(() => {
|
||
const els = document.querySelectorAll('.lp-reveal');
|
||
const io = new IntersectionObserver(
|
||
(entries) => entries.forEach((e) => e.isIntersecting && e.target.classList.add('lp-in')),
|
||
{ threshold: 0.14 }
|
||
);
|
||
els.forEach((el) => io.observe(el));
|
||
return () => io.disconnect();
|
||
}, []);
|
||
};
|
||
|
||
const CountUp = ({ to, suffix = '', duration = 1600 }) => {
|
||
const ref = useRef(null);
|
||
const [val, setVal] = useState(0);
|
||
useEffect(() => {
|
||
const el = ref.current;
|
||
if (!el) return;
|
||
let raf, started = false;
|
||
const io = new IntersectionObserver(([entry]) => {
|
||
if (!entry.isIntersecting || started) return;
|
||
started = true;
|
||
const t0 = performance.now();
|
||
const tick = (t) => {
|
||
const p = Math.min(1, (t - t0) / duration);
|
||
setVal(Math.round(to * (1 - Math.pow(1 - p, 3))));
|
||
if (p < 1) raf = requestAnimationFrame(tick);
|
||
};
|
||
raf = requestAnimationFrame(tick);
|
||
}, { threshold: 0.5 });
|
||
io.observe(el);
|
||
return () => { io.disconnect(); cancelAnimationFrame(raf); };
|
||
}, [to, duration]);
|
||
return <span ref={ref}>{val.toLocaleString('tr-TR')}{suffix}</span>;
|
||
};
|
||
|
||
/* ---------- örnek akış verisi (görsel amaçlı) ---------- */
|
||
|
||
const TICKER = [
|
||
{ k: 'Yapım İşi', t: 'Okul binası güçlendirme', c: 'Ankara', renk: '#fbbf24' },
|
||
{ k: 'Mal Alımı', t: 'Tıbbi sarf malzemesi', c: 'İzmir', renk: '#22d3ee' },
|
||
{ k: 'Hizmet', t: 'Personel taşıma 12 ay', c: 'Bursa', renk: '#a78bfa' },
|
||
{ k: '22/d', t: 'Bilgisayar ve çevre birimleri', c: 'İstanbul', renk: '#34d399' },
|
||
{ k: 'Yapım İşi', t: 'İçme suyu hattı yenileme', c: 'Konya', renk: '#fbbf24' },
|
||
{ k: 'Mal Alımı', t: 'Araç lastiği alımı', c: 'Antalya', renk: '#22d3ee' },
|
||
{ k: 'Hizmet', t: 'Yemek hazırlama ve dağıtım', c: 'Gaziantep', renk: '#a78bfa' },
|
||
{ k: '22/d', t: 'Kırtasiye malzemesi', c: 'Trabzon', renk: '#34d399' },
|
||
];
|
||
|
||
const OZELLIKLER = [
|
||
{ icon: Zap, baslik: 'Canlı ihale akışı', metin: 'ilan.gov.tr ilanları dakikalar içinde ekranınızda. Şehir, sektör ve bütçeye göre süzün; hiçbir fırsatı kaçırmayın.', renk: 'from-cyan-400/20 to-cyan-400/0', ikon: 'text-cyan-300' },
|
||
{ icon: FileSearch, baslik: 'AI şartname analizi', metin: 'Yüzlerce sayfalık şartnameyi yükleyin; yeterlilik şartları, riskler ve kritik tarihler saniyeler içinde özetlensin.', renk: 'from-amber-400/20 to-amber-400/0', ikon: 'text-amber-300' },
|
||
{ icon: Kanban, baslik: 'Kanban süreç takibi', metin: 'İlgilendiğiniz ihaleleri panoya taşıyın: İnceleme → Teklif Hazırlığı → Verildi → Sonuç. Ekipçe aynı ekranda.', renk: 'from-violet-400/20 to-violet-400/0', ikon: 'text-violet-300' },
|
||
{ icon: Radar, baslik: 'Rakip radarı', metin: 'Hangi firma hangi ihaleyi, hangi bedelle kazandı? Rakiplerinizin izini sürün, stratejinizi veriyle kurun.', renk: 'from-rose-400/20 to-rose-400/0', ikon: 'text-rose-300' },
|
||
{ icon: TrendingUp, baslik: 'Fiyat & piyasa analizi', metin: 'Geçmiş sonuçlardan yaklaşık maliyet ve kırım oranı analizi. Teklifinizi tahminle değil, veriyle verin.', renk: 'from-emerald-400/20 to-emerald-400/0', ikon: 'text-emerald-300' },
|
||
{ icon: Bell, baslik: 'Günlük bülten & uyarılar', metin: 'Kriterlerinize uyan yeni ilanlar her sabah e-postanızda. Son teklif tarihi yaklaşınca otomatik hatırlatma.', renk: 'from-sky-400/20 to-sky-400/0', ikon: 'text-sky-300' },
|
||
{ icon: Microscope, baslik: 'Derin analiz + yol haritası', yeni: true, metin: 'Şartname, sözleşme ve teklif cetvelini birlikte okur: elenme riskleri, gözden kaçan ince detaylar, kalem özellikleri, belge kontrol listesi ve teklif gününe geri sayan adım adım yol haritası.', renk: 'from-fuchsia-400/20 to-fuchsia-400/0', ikon: 'text-fuchsia-300' },
|
||
{ icon: Tag, baslik: 'AB uyumlu CPV sınıflandırması', metin: 'Türkiye\'de bir ilk: her ihale, Avrupa Birliği standardı CPV koduna göre otomatik sınıflandırılır. Sektörünüze uyan ihaleleri AB standardında filtreleyin.', renk: 'from-teal-400/20 to-teal-400/0', ikon: 'text-teal-300' },
|
||
];
|
||
|
||
/* ---------- bileşenler ---------- */
|
||
|
||
const TickerRow = ({ reverse = false }) => (
|
||
<div className="lp-ticker-mask overflow-hidden">
|
||
<div className={`flex w-max gap-3 ${reverse ? 'lp-marquee-rev' : 'lp-marquee'}`}>
|
||
{[...TICKER, ...TICKER].map((x, i) => (
|
||
<div key={i} className="flex shrink-0 items-center gap-2.5 rounded-full border border-white/10 bg-white/[0.05] px-4 py-2 text-sm backdrop-blur">
|
||
<span className="h-2 w-2 rounded-full" style={{ background: x.renk }} />
|
||
<span className="font-semibold text-white/90">{x.t}</span>
|
||
<span className="text-white/40">·</span>
|
||
<span className="flex items-center gap-1 text-white/50"><MapPin size={12} />{x.c}</span>
|
||
<span className="rounded-full px-2 py-0.5 text-[11px] font-bold" style={{ background: `${x.renk}22`, color: x.renk }}>{x.k}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
|
||
const MockDashboard = () => (
|
||
<div className="relative mx-auto w-full max-w-xl lp-float">
|
||
<div className="absolute -inset-8 rounded-[2.5rem] bg-gradient-to-tr from-cyan-500/25 via-violet-500/15 to-amber-400/25 blur-3xl" aria-hidden="true" />
|
||
<div className="relative overflow-hidden rounded-2xl border border-white/12 bg-[#101a2e] shadow-[0_40px_120px_-30px_rgba(34,211,238,0.35)]">
|
||
<div className="flex h-11 items-center gap-2 border-b border-white/8 bg-white/[0.04] px-4">
|
||
<span className="h-2.5 w-2.5 rounded-full bg-rose-400/80" />
|
||
<span className="h-2.5 w-2.5 rounded-full bg-amber-400/80" />
|
||
<span className="h-2.5 w-2.5 rounded-full bg-emerald-400/80" />
|
||
<span className="ml-3 flex items-center gap-1.5 text-xs font-semibold text-white/50">
|
||
<span className="lp-blink h-1.5 w-1.5 rounded-full bg-emerald-400" /> ihaleist · canlı akış
|
||
</span>
|
||
</div>
|
||
<div className="space-y-2.5 p-4">
|
||
{[
|
||
{ t: 'Hastane ek bina inşaatı', b: '₺48,2M', s: 'Teklif Hazırlığı', sr: 'bg-amber-400/15 text-amber-300', g: 8, d: 0 },
|
||
{ t: 'Ağ altyapısı yenileme', b: '₺6,7M', s: 'Yeni İlan', sr: 'bg-cyan-400/15 text-cyan-300', g: 3, d: 1 },
|
||
{ t: 'Araç kiralama 24 ay', b: '₺12,4M', s: 'İnceleme', sr: 'bg-violet-400/15 text-violet-300', g: 15, d: 2 },
|
||
].map((r, i) => (
|
||
<div key={i} className="lp-card-in rounded-xl border border-white/8 bg-white/[0.04] p-3.5 transition-colors hover:bg-white/[0.07]" style={{ animationDelay: `${0.35 + r.d * 0.22}s` }}>
|
||
<div className="flex items-start justify-between gap-3">
|
||
<div className="min-w-0">
|
||
<div className="flex items-center gap-2">
|
||
<Gavel size={14} className="shrink-0 text-cyan-300" />
|
||
<span className="truncate text-sm font-bold text-white">{r.t}</span>
|
||
</div>
|
||
<div className="mt-1.5 flex items-center gap-3 text-xs text-white/45">
|
||
<span className="flex items-center gap-1"><Building2 size={11} /> Kamu kurumu</span>
|
||
<span className="flex items-center gap-1"><Timer size={11} /> {r.g} gün kaldı</span>
|
||
</div>
|
||
</div>
|
||
<div className="text-right">
|
||
<div className="font-mono text-sm font-black text-emerald-300">{r.b}</div>
|
||
<span className={`mt-1 inline-block rounded-full px-2 py-0.5 text-[10px] font-bold ${r.sr}`}>{r.s}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
))}
|
||
<div className="grid grid-cols-4 items-end gap-2 rounded-xl border border-white/8 bg-white/[0.04] p-3.5">
|
||
<div className="col-span-4 mb-1 flex items-center justify-between">
|
||
<span className="flex items-center gap-1.5 text-xs font-semibold text-white/60"><ChartNoAxesCombined size={13} className="text-amber-300" /> Kırım oranı analizi</span>
|
||
<span className="text-[10px] font-bold text-white/35">SON 6 AY</span>
|
||
</div>
|
||
{[42, 68, 55, 80, 62, 90, 74, 96].map((h, i) => (
|
||
<div key={i} className="lp-bar rounded-t-md bg-gradient-to-t from-cyan-500/60 to-cyan-300" style={{ '--h': `${h * 0.5}px`, animationDelay: `${0.9 + i * 0.09}s` }} />
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div className="lp-sticker absolute -right-4 -top-5 rotate-6 rounded-xl border border-amber-300/30 bg-amber-400 px-3.5 py-2 text-xs font-black text-amber-950 shadow-lg shadow-amber-500/30">
|
||
<Sparkles size={13} className="mr-1 inline" /> AI özetledi: 3 kritik şart
|
||
</div>
|
||
<div className="lp-sticker absolute -bottom-4 -left-3 -rotate-3 rounded-xl border border-white/15 bg-[#16233c] px-3.5 py-2 text-xs font-bold text-white shadow-xl" style={{ animationDelay: '1.4s' }}>
|
||
🔔 Bugün size uyan <span className="text-cyan-300">14 yeni ilan</span>
|
||
</div>
|
||
</div>
|
||
);
|
||
|
||
const Adim = ({ no, baslik, metin, gecikme }) => (
|
||
<div className="lp-reveal group relative rounded-2xl border border-white/10 bg-white/[0.04] p-7 transition duration-300 hover:-translate-y-1.5 hover:border-cyan-300/30 hover:bg-white/[0.06]" style={{ transitionDelay: gecikme }}>
|
||
<div className="font-mono text-5xl font-black text-white/8 transition group-hover:text-cyan-300/20">{no}</div>
|
||
<h3 className="mt-4 text-xl font-black text-white">{baslik}</h3>
|
||
<p className="mt-2.5 text-sm leading-7 text-white/55">{metin}</p>
|
||
</div>
|
||
);
|
||
|
||
/* ---------- sayfa ---------- */
|
||
|
||
export const LandingPage = ({ onGiris }) => {
|
||
useReveal();
|
||
const yil = new Date().getFullYear();
|
||
|
||
return (
|
||
<div className="lp-root min-h-screen overflow-x-hidden bg-[#0a1122] text-white antialiased">
|
||
{/* arkaplan */}
|
||
<div className="pointer-events-none fixed inset-0" aria-hidden="true">
|
||
<div className="lp-blob absolute -top-40 left-1/4 h-[520px] w-[520px] rounded-full bg-cyan-500/14 blur-[110px]" />
|
||
<div className="lp-blob absolute right-[-10%] top-1/3 h-[460px] w-[460px] rounded-full bg-violet-500/12 blur-[110px]" style={{ animationDelay: '-6s' }} />
|
||
<div className="lp-blob absolute bottom-[-15%] left-[-5%] h-[420px] w-[420px] rounded-full bg-amber-400/10 blur-[110px]" style={{ animationDelay: '-12s' }} />
|
||
<div className="lp-grid absolute inset-0 opacity-[0.35]" />
|
||
</div>
|
||
|
||
{/* nav */}
|
||
<header className="relative z-40 mx-auto flex max-w-7xl items-center justify-between px-5 py-5 sm:px-8">
|
||
<div className="flex items-center gap-2.5">
|
||
<span className="flex h-10 w-10 items-center justify-center rounded-xl bg-gradient-to-br from-cyan-400 to-blue-600 shadow-lg shadow-cyan-500/30">
|
||
<Gavel size={20} className="text-white" />
|
||
</span>
|
||
<span className="text-xl font-black tracking-tight">ihale<span className="text-cyan-300">ist</span></span>
|
||
</div>
|
||
<nav className="hidden items-center gap-8 text-sm font-semibold text-white/60 md:flex">
|
||
<a href="#ozellikler" className="transition hover:text-white">Özellikler</a>
|
||
<a href="#yenilikler" className="flex items-center gap-1 transition hover:text-white">Yenilikler <span className="rounded bg-fuchsia-500 px-1 text-[9px] font-black text-white">{YENILIKLER.length}</span></a>
|
||
<a href="#nasil" className="transition hover:text-white">Nasıl çalışır?</a>
|
||
<a href="#rakamlar" className="transition hover:text-white">Rakamlarla</a>
|
||
</nav>
|
||
<button onClick={onGiris} className="group flex items-center gap-2 rounded-xl bg-white px-5 py-2.5 text-sm font-black text-slate-900 transition hover:bg-cyan-300">
|
||
Giriş Yap <ArrowRight size={15} className="transition group-hover:translate-x-0.5" />
|
||
</button>
|
||
</header>
|
||
|
||
{/* hero */}
|
||
<section className="relative z-10 mx-auto max-w-7xl px-5 pb-16 pt-10 sm:px-8 sm:pt-16">
|
||
<div className="grid items-center gap-14 lg:grid-cols-[1.02fr_0.98fr]">
|
||
<div>
|
||
<div className="lp-hero-in inline-flex items-center gap-2 rounded-full border border-cyan-300/25 bg-cyan-400/10 px-4 py-1.5 text-xs font-bold text-cyan-200">
|
||
<span className="lp-blink h-1.5 w-1.5 rounded-full bg-emerald-400" />
|
||
ilan.gov.tr akışı şu anda canlı
|
||
</div>
|
||
<h1 className="lp-hero-in mt-6 text-5xl font-black leading-[1.04] tracking-tight sm:text-6xl xl:text-7xl" style={{ animationDelay: '0.08s' }}>
|
||
Kamu ihalelerini
|
||
<br />
|
||
<span className="lp-gradient-text">kaçırmayan</span> firma,
|
||
<br />
|
||
kazanan firmadır.
|
||
</h1>
|
||
<p className="lp-hero-in mt-6 max-w-xl text-lg leading-8 text-white/60" style={{ animationDelay: '0.16s' }}>
|
||
İhaleist; canlı ilan akışını, yapay zekâ destekli şartname analizini, rakip takibini ve
|
||
fiyat analizini tek panelde toplar. Siz teklife odaklanın, takibi biz yapalım.
|
||
</p>
|
||
<div className="lp-hero-in mt-9 flex flex-col gap-3 sm:flex-row" style={{ animationDelay: '0.24s' }}>
|
||
<button onClick={onGiris} className="group flex items-center justify-center gap-2 rounded-xl bg-gradient-to-r from-cyan-400 to-blue-500 px-7 py-3.5 text-base font-black text-white shadow-xl shadow-cyan-500/25 transition hover:shadow-cyan-400/40 hover:brightness-110">
|
||
Hemen Başla — Ücretsiz <ArrowRight size={17} className="transition group-hover:translate-x-1" />
|
||
</button>
|
||
<a href="#ozellikler" className="flex items-center justify-center gap-2 rounded-xl border border-white/15 bg-white/[0.05] px-7 py-3.5 text-base font-bold text-white/85 backdrop-blur transition hover:border-white/30 hover:bg-white/10">
|
||
Neler yapabilir?
|
||
</a>
|
||
</div>
|
||
<div className="lp-hero-in mt-7 flex flex-wrap gap-x-6 gap-y-2 text-sm font-medium text-white/45" style={{ animationDelay: '0.32s' }}>
|
||
<span className="flex items-center gap-1.5"><CheckCircle2 size={15} className="text-emerald-400" /> Google ile 10 saniyede giriş</span>
|
||
<span className="flex items-center gap-1.5"><CheckCircle2 size={15} className="text-emerald-400" /> Kurulum gerekmez</span>
|
||
<span className="flex items-center gap-1.5"><CheckCircle2 size={15} className="text-emerald-400" /> KVKK uyumlu</span>
|
||
</div>
|
||
</div>
|
||
<MockDashboard />
|
||
</div>
|
||
</section>
|
||
|
||
{/* akış şeridi */}
|
||
<section className="relative z-10 space-y-3 py-6">
|
||
<TickerRow />
|
||
<TickerRow reverse />
|
||
</section>
|
||
|
||
{/* rakamlar */}
|
||
<section id="rakamlar" className="relative z-10 mx-auto max-w-7xl scroll-mt-24 px-5 py-16 sm:px-8">
|
||
<div className="lp-reveal grid gap-4 rounded-3xl border border-white/10 bg-gradient-to-r from-cyan-500/[0.08] via-white/[0.04] to-violet-500/[0.08] p-8 sm:grid-cols-2 sm:p-10 lg:grid-cols-4">
|
||
{[
|
||
{ v: 2400, s: '+', l: 'Günlük yeni ilan taranıyor', i: Zap, r: 'text-cyan-300' },
|
||
{ v: 81, s: '', l: 'İl genelinde takip', i: MapPin, r: 'text-amber-300' },
|
||
{ v: 15000, s: '+', l: 'Kayıtlı kamu kurumu', i: Building2, r: 'text-violet-300' },
|
||
{ v: 30, s: ' sn', l: 'Ortalama şartname özeti', i: Sparkles, r: 'text-emerald-300' },
|
||
].map((x) => (
|
||
<div key={x.l} className="flex flex-col items-center gap-1 text-center">
|
||
<x.i size={22} className={x.r} />
|
||
<div className="mt-2 text-4xl font-black tracking-tight"><CountUp to={x.v} suffix={x.s} /></div>
|
||
<div className="text-sm font-medium text-white/50">{x.l}</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</section>
|
||
|
||
{/* özellikler */}
|
||
<section id="ozellikler" className="relative z-10 mx-auto max-w-7xl scroll-mt-24 px-5 py-16 sm:px-8">
|
||
<div className="lp-reveal max-w-2xl">
|
||
<span className="text-xs font-black uppercase tracking-[0.22em] text-cyan-300">Tek panel, tam kontrol</span>
|
||
<h2 className="mt-4 text-4xl font-black tracking-tight sm:text-5xl">İhale masanızın <span className="lp-underline">tamamı</span> burada.</h2>
|
||
<p className="mt-4 text-lg leading-8 text-white/55">EKAP'ta, gazete ilanlarında, kurum sitelerinde dağınık duran her şey — tek akışta, süzülmüş ve önceliklendirilmiş.</p>
|
||
</div>
|
||
<div className="mt-12 grid gap-5 sm:grid-cols-2 lg:grid-cols-3">
|
||
{OZELLIKLER.map((o, i) => (
|
||
<article key={o.baslik} className="lp-reveal group relative overflow-hidden rounded-2xl border border-white/10 bg-white/[0.04] p-7 transition duration-300 hover:-translate-y-1.5 hover:border-white/25" style={{ transitionDelay: `${(i % 3) * 90}ms` }}>
|
||
<div className={`pointer-events-none absolute inset-0 bg-gradient-to-br opacity-0 transition duration-300 group-hover:opacity-100 ${o.renk}`} aria-hidden="true" />
|
||
<div className="relative">
|
||
<span className={`flex h-12 w-12 items-center justify-center rounded-xl border border-white/10 bg-white/[0.06] ${o.ikon}`}><o.icon size={22} /></span>
|
||
<h3 className="mt-6 flex items-center gap-2 text-xl font-black">{o.baslik}{o.yeni && <span className="rounded-md bg-fuchsia-500 px-1.5 py-0.5 text-[10px] font-black uppercase tracking-wider text-white">Yeni</span>}</h3>
|
||
<p className="mt-2.5 text-sm leading-7 text-white/55">{o.metin}</p>
|
||
</div>
|
||
</article>
|
||
))}
|
||
</div>
|
||
</section>
|
||
|
||
{/* yeni eklenenler */}
|
||
<section id="yenilikler" className="relative z-10 mx-auto max-w-7xl scroll-mt-24 px-5 py-16 sm:px-8">
|
||
<div className="lp-reveal max-w-2xl">
|
||
<span className="text-xs font-black uppercase tracking-[0.22em] text-fuchsia-300">Yeni eklenenler</span>
|
||
<h2 className="mt-4 text-4xl font-black tracking-tight sm:text-5xl">Dosyayı hazırlayan, <span className="lp-underline">sınırı hesaplayan</span> ihale masası.</h2>
|
||
<p className="mt-4 text-lg leading-8 text-white/55">Analizden teklif dosyasına, sınır değerden Telegram uyarısına — son güncellemeyle eklenen {YENILIKLER.length} yeni yetenek.</p>
|
||
</div>
|
||
<div className="mt-12 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||
{YENILIKLER.map((y, i) => (
|
||
<article key={y.baslik} className="lp-reveal group relative flex gap-4 rounded-2xl border border-white/10 bg-white/[0.04] p-5 transition duration-300 hover:-translate-y-1 hover:border-fuchsia-300/40" style={{ transitionDelay: `${(i % 3) * 80}ms` }}>
|
||
<span className="flex h-11 w-11 shrink-0 items-center justify-center rounded-xl border border-fuchsia-300/20 bg-fuchsia-400/10 text-fuchsia-300"><y.icon size={20} /></span>
|
||
<div>
|
||
<h3 className="text-base font-black leading-snug">{y.baslik}</h3>
|
||
<p className="mt-1.5 text-sm leading-6 text-white/55">{y.metin}</p>
|
||
</div>
|
||
</article>
|
||
))}
|
||
</div>
|
||
</section>
|
||
|
||
{/* nasıl çalışır */}
|
||
<section id="nasil" className="relative z-10 mx-auto max-w-7xl scroll-mt-24 px-5 py-16 sm:px-8">
|
||
<div className="lp-reveal text-center">
|
||
<span className="text-xs font-black uppercase tracking-[0.22em] text-amber-300">Nasıl çalışır?</span>
|
||
<h2 className="mt-4 text-4xl font-black tracking-tight sm:text-5xl">Üç adımda ihale radarınız hazır.</h2>
|
||
</div>
|
||
<div className="mt-12 grid gap-5 lg:grid-cols-3">
|
||
<Adim no="01" baslik="Giriş yapın, kriterinizi kurun" metin="Google hesabınızla girin; sektör, şehir ve bütçe aralığınızı seçin. Akıllı filtre motoru gerisini halleder." gecikme="0ms" />
|
||
<Adim no="02" baslik="Akışı ve bülteni takip edin" metin="Size uyan ilanlar panelde ve her sabah e-posta bülteninizde. Şartnameyi AI'a özetletin, riskleri görün." gecikme="120ms" />
|
||
<Adim no="03" baslik="Teklif verin, süreci yönetin" metin="Kanban'da süreci ekiple yürütün; sonuç ilanlarından rakip ve fiyat analizine geçip bir sonraki teklifinizi güçlendirin." gecikme="240ms" />
|
||
</div>
|
||
</section>
|
||
|
||
{/* son çağrı */}
|
||
<section className="relative z-10 mx-auto max-w-7xl px-5 py-20 sm:px-8">
|
||
<div className="lp-reveal relative overflow-hidden rounded-[2rem] border border-cyan-300/20 bg-gradient-to-br from-[#0e2036] via-[#101a2e] to-[#1a1035] px-7 py-16 text-center shadow-2xl sm:px-14">
|
||
<div className="lp-blob absolute -right-24 -top-24 h-72 w-72 rounded-full bg-cyan-400/15 blur-[90px]" aria-hidden="true" />
|
||
<div className="lp-blob absolute -bottom-24 -left-24 h-72 w-72 rounded-full bg-amber-400/12 blur-[90px]" style={{ animationDelay: '-8s' }} aria-hidden="true" />
|
||
<div className="relative">
|
||
<CalendarDays size={34} className="mx-auto text-cyan-300" />
|
||
<h2 className="mx-auto mt-5 max-w-2xl text-4xl font-black tracking-tight sm:text-5xl">Yarınki ilanlar sizi beklemeyecek.</h2>
|
||
<p className="mx-auto mt-4 max-w-xl text-lg leading-8 text-white/55">Bugün girin, kriterlerinizi kurun; yarın sabah ilk bülteniniz hazır olsun.</p>
|
||
<button onClick={onGiris} className="group mx-auto mt-9 flex items-center gap-2 rounded-xl bg-gradient-to-r from-cyan-400 to-blue-500 px-8 py-4 text-lg font-black text-white shadow-xl shadow-cyan-500/30 transition hover:shadow-cyan-400/50 hover:brightness-110">
|
||
Ücretsiz Giriş Yap <ArrowRight size={19} className="transition group-hover:translate-x-1" />
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* footer */}
|
||
<footer className="relative z-10 border-t border-white/8 px-5 py-9 sm:px-8">
|
||
<div className="mx-auto flex max-w-7xl flex-col items-center justify-between gap-5 text-sm text-white/40 sm:flex-row">
|
||
<div className="flex items-center gap-2">
|
||
<span className="flex h-7 w-7 items-center justify-center rounded-lg bg-gradient-to-br from-cyan-400 to-blue-600"><Gavel size={14} className="text-white" /></span>
|
||
<span className="font-black text-white/80">ihale<span className="text-cyan-300">ist</span></span>
|
||
<span className="ml-2">© {yil}</span>
|
||
</div>
|
||
<div className="flex flex-wrap items-center gap-x-6 gap-y-2 font-semibold">
|
||
<a href="/gizlilik.html" className="transition hover:text-white">Gizlilik Politikası</a>
|
||
<a href="/kullanim-kosullari.html" className="transition hover:text-white">Kullanım Şartları</a>
|
||
<button onClick={onGiris} className="transition hover:text-white">Giriş</button>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
</div>
|
||
);
|
||
};
|