Files
kovakyazilim/components/solution-hero.tsx
T
egecankomur 2e001680bf feat: Çözümler bölümü + mobil menü; admin parser düzeltmeleri
- Çözümler: solutions tablosu, /cozumler liste + detay sayfası, anasayfa
  bölümü, tam admin CRUD (/admin/cozumler), header & footer linkleri,
  projelerde solution_slug ilişkisi, services-grid genelleştirildi
- Mobil menü (hamburger drawer) eklendi — header artık < lg'de gezilebilir
- Site ayarları parser: textarea CRLF (\r\n) normalizasyonu — neden biz,
  süreç adımları, değerler ve SSS blokları artık doğru parçalanıyor
- homepage_faq + garanti (title/description/items) saveSiteSettings'e
  bağlandı (daha önce hiç kaydedilmiyordu)
2026-06-02 18:21:58 +03:00

210 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Image from "next/image";
import Link from "next/link";
import { ArrowLeft, ArrowRight, MessageCircle, Phone, Sparkles, CheckCircle2 } from "lucide-react";
import { Icon } from "@/components/icon";
import type { SolutionRow, SiteSettingsRow } from "@/lib/types";
import { siteConfig } from "@/lib/site-config";
const QUICK_TRUST = [
"İşletmenize özel kurgu",
"Tek elden uçtan uca",
"Ücretsiz keşif görüşmesi",
"Yerel ekip — Kocaeli",
];
export function SolutionHero({
solution,
settings,
}: {
solution: SolutionRow;
settings?: SiteSettingsRow | null;
}) {
const phoneRaw = settings?.contact_phone_raw ?? siteConfig.contact.phoneRaw;
const phone = settings?.contact_phone ?? siteConfig.contact.phone;
const wa = phoneRaw.replace(/[^\d]/g, "");
const waMessage = settings?.whatsapp_message ?? `Merhaba, ${solution.title} çözümü hakkında bilgi almak istiyorum.`;
const waHref = `https://wa.me/${wa}?text=${encodeURIComponent(waMessage)}`;
return (
<section className="relative overflow-hidden border-b border-[var(--border)] bg-gradient-to-br from-[var(--navy-50)]/60 via-white to-[var(--sky-50)]/40">
{/* Subtle grid + glow */}
<div className="absolute inset-0 hero-grid opacity-50" aria-hidden />
<div
className="absolute -right-32 top-1/2 size-[520px] -translate-y-1/2 rounded-full bg-gradient-to-br from-[var(--sky)]/15 to-transparent blur-3xl"
aria-hidden
/>
<div className="relative mx-auto max-w-7xl px-6 py-16 lg:py-20">
<Link
href="/cozumler"
className="inline-flex items-center gap-1 text-sm text-[var(--muted)] hover:text-[var(--navy)]"
>
<ArrowLeft className="size-3.5" /> Tüm çözümler
</Link>
<div className="mt-8 grid items-start gap-12 lg:grid-cols-[1.3fr_1fr]">
{/* Left — content */}
<div>
<div className="flex items-center gap-3">
<div className="relative">
<div
className="absolute inset-0 -z-10 rounded-2xl bg-gradient-to-br from-[var(--sky)] to-purple-500 blur-md opacity-50"
aria-hidden
/>
<div className="flex size-16 items-center justify-center rounded-2xl bg-gradient-to-br from-[var(--sky)] to-purple-500 text-white shadow-lg">
<Icon name={solution.icon} className="size-8" />
</div>
</div>
<span className="inline-flex items-center gap-2 rounded-full border border-[var(--sky)]/30 bg-white px-3 py-1 text-xs font-medium text-[var(--sky-600)]">
<Sparkles className="size-3.5" />
İşletmenize özel çözüm
</span>
</div>
<h1 className="mt-6 text-4xl font-extrabold leading-[1.1] tracking-tight text-[var(--navy)] sm:text-5xl lg:text-6xl">
<span className="gradient-text">{solution.title}</span>
</h1>
<p className="mt-5 max-w-xl text-lg leading-relaxed text-[var(--muted)]">
{solution.description}
</p>
{/* Quick trust strip */}
<ul className="mt-8 grid max-w-xl grid-cols-2 gap-2">
{QUICK_TRUST.map((it) => (
<li
key={it}
className="flex items-center gap-2 text-sm text-[var(--foreground)]"
>
<CheckCircle2 className="size-4 shrink-0 text-[var(--sky-600)]" />
{it}
</li>
))}
</ul>
<div className="mt-8 flex flex-col gap-3 sm:flex-row">
<Link
href="/iletisim"
className="inline-flex items-center justify-center gap-2 rounded-xl bg-[var(--navy)] px-6 py-3.5 text-sm font-semibold text-white shadow-lg shadow-[var(--navy)]/20 transition hover:-translate-y-0.5 hover:bg-[var(--navy-700)]"
>
Ücretsiz teklif al
<ArrowRight className="size-4" />
</Link>
<a
href={waHref}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center gap-2 rounded-xl bg-[#25d366] px-6 py-3.5 text-sm font-semibold text-white shadow-lg shadow-[#25d366]/20 transition hover:-translate-y-0.5 hover:bg-[#1ebe5d]"
>
<MessageCircle className="size-4" />
WhatsApp'tan yaz
</a>
<a
href={`tel:${phoneRaw}`}
className="inline-flex items-center justify-center gap-2 rounded-xl border border-[var(--border)] bg-white px-6 py-3.5 text-sm font-semibold text-[var(--navy)] transition hover:border-[var(--navy)]"
>
<Phone className="size-4" />
{phone}
</a>
</div>
</div>
{/* Right — hero card */}
<div className="relative">
{solution.hero_image ? (
<div className="relative aspect-[4/5] overflow-hidden rounded-3xl shadow-2xl shadow-[var(--navy)]/10">
<Image
src={solution.hero_image}
alt={solution.title}
fill
sizes="(min-width: 1024px) 480px, 100vw"
className="object-cover"
priority
/>
{/* Floating badge */}
<div className="absolute bottom-4 left-4 right-4 rounded-xl bg-white/95 p-4 backdrop-blur shadow-lg">
<p className="text-xs font-semibold uppercase tracking-wider text-[var(--sky-600)]">
Şimdi başla
</p>
<p className="mt-1 text-sm font-bold text-[var(--navy)]">
Ücretsiz keşif görüşmesi
</p>
</div>
</div>
) : (
<DecorativeSolutionCard solution={solution} />
)}
</div>
</div>
</div>
</section>
);
}
function DecorativeSolutionCard({ solution }: { solution: SolutionRow }) {
return (
<div className="relative">
{/* Outer gradient frame */}
<div className="relative overflow-hidden rounded-3xl bg-gradient-to-br from-[var(--navy)] via-[var(--sky-600)] to-[var(--sky)] p-px shadow-2xl shadow-[var(--navy)]/20">
<div className="relative rounded-3xl bg-[#0f172a] p-8">
{/* Animated dots */}
<div
className="absolute inset-0 opacity-20"
style={{
backgroundImage:
"radial-gradient(circle at 1px 1px, white 1px, transparent 0)",
backgroundSize: "24px 24px",
}}
aria-hidden
/>
{/* Glow */}
<div className="absolute -right-20 -top-20 size-64 rounded-full bg-[var(--sky)]/30 blur-3xl" aria-hidden />
{/* Card content */}
<div className="relative">
<div className="flex size-20 items-center justify-center rounded-2xl bg-white/10 backdrop-blur ring-1 ring-white/20">
<Icon name={solution.icon} className="size-10 text-[var(--sky)]" />
</div>
<div className="mt-8 space-y-2 text-white">
<p className="text-[11px] font-mono uppercase tracking-[0.2em] text-[var(--sky)]">
kovak.yazilim
</p>
<p className="text-2xl font-bold leading-tight">
{solution.title}
</p>
<p className="text-sm leading-relaxed text-white/60">
İşletmenize özel, uçtan uca çözüm.
</p>
</div>
{/* Bottom badges */}
<div className="mt-8 flex flex-wrap gap-2">
<span className="rounded-full bg-white/10 px-3 py-1 text-[10px] font-medium text-white/80 ring-1 ring-white/10">
Hızlı
</span>
<span className="rounded-full bg-white/10 px-3 py-1 text-[10px] font-medium text-white/80 ring-1 ring-white/10">
🛡 Garantili
</span>
<span className="rounded-full bg-white/10 px-3 py-1 text-[10px] font-medium text-white/80 ring-1 ring-white/10">
📞 7/24 Destek
</span>
</div>
</div>
</div>
</div>
{/* Floating accent */}
<div className="absolute -right-4 -top-4 rounded-2xl bg-white p-4 shadow-xl ring-1 ring-[var(--border)]">
<p className="text-xs font-medium text-[var(--muted)]">Memnuniyet</p>
<p className="text-2xl font-bold text-[var(--navy)]">100%</p>
</div>
<div className="absolute -bottom-4 -left-4 rounded-2xl bg-white p-4 shadow-xl ring-1 ring-[var(--border)]">
<p className="text-xs font-medium text-[var(--muted)]">Proje</p>
<p className="text-2xl font-bold text-[var(--navy)]">150+</p>
</div>
</div>
);
}