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)
This commit is contained in:
egecankomur
2026-06-02 18:21:58 +03:00
parent f49df9cbeb
commit 2e001680bf
21 changed files with 1191 additions and 27 deletions
+145
View File
@@ -0,0 +1,145 @@
import Link from "next/link";
import { ArrowRight, MessageCircle, Phone, ShieldCheck } from "lucide-react";
import { Icon } from "@/components/icon";
import { getSiteSettings, listSolutions } from "@/lib/data";
import { siteConfig } from "@/lib/site-config";
import { QuickLeadForm } from "@/components/quick-lead-form";
export async function SolutionSidebar({
currentSlug,
}: {
currentSlug: string;
}) {
const [settings, solutions] = await Promise.all([
getSiteSettings(),
listSolutions(),
]);
const otherSolutions = solutions
.filter((s) => s.slug !== currentSlug)
.slice(0, 6);
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 ?? "";
const waHref = `https://wa.me/${wa}${
waMessage ? `?text=${encodeURIComponent(waMessage)}` : ""
}`;
return (
<aside className="space-y-5 lg:sticky lg:top-24 lg:self-start">
{/* Quick lead form */}
<QuickLeadForm
title="Bu çözüm için teklif"
description="Adınızı ve telefonunuzu bırakın, 24 saat içinde sizi arayalım."
buttonLabel="Beni arayın"
/>
{/* CTA card */}
<div className="overflow-hidden rounded-2xl border border-[var(--border)] bg-gradient-to-br from-[var(--navy)] to-[var(--sky-600)] p-6 text-white">
<h3 className="text-base font-bold">Hızlı iletişim</h3>
<p className="mt-1 text-sm text-white/80">
Telefon veya WhatsApp ile dakikalar içinde konuşalım.
</p>
<div className="mt-4 space-y-2">
<a
href={`tel:${phoneRaw}`}
className="flex items-center justify-center gap-2 rounded-xl bg-white px-4 py-2.5 text-sm font-semibold text-[var(--navy)] transition hover:bg-blue-50"
>
<Phone className="size-3.5" />
{phone}
</a>
<a
href={waHref}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center gap-2 rounded-xl bg-[#25d366] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-[#1ebe5d]"
>
<MessageCircle className="size-3.5" />
WhatsApp'tan yaz
</a>
</div>
</div>
{/* Guarantee mini */}
<div className="rounded-2xl border border-[var(--sky)]/30 bg-[var(--sky-50)]/50 p-5">
<div className="flex items-center gap-2">
<ShieldCheck className="size-5 text-[var(--sky-600)]" />
<h3 className="text-sm font-bold text-[var(--navy)]">
Risk almazsınız
</h3>
</div>
<ul className="mt-3 space-y-1.5 text-xs text-[var(--foreground)]">
<li className="flex gap-1.5">
<span className="text-[var(--sky-600)]"></span>
Ücretsiz keşif görüşmesi
</li>
<li className="flex gap-1.5">
<span className="text-[var(--sky-600)]"></span>
1 yıl ücretsiz teknik destek
</li>
<li className="flex gap-1.5">
<span className="text-[var(--sky-600)]"></span>
Kaynak kodlar size ait
</li>
</ul>
</div>
{/* Diğer çözümler — full list */}
{otherSolutions.length > 0 && (
<div className="rounded-2xl border border-[var(--border)] bg-white p-5">
<div className="flex items-center justify-between">
<h3 className="text-sm font-bold uppercase tracking-wider text-[var(--navy)]">
Diğer çözümler
</h3>
<Link
href="/cozumler"
className="text-xs text-[var(--sky-600)] hover:text-[var(--navy)]"
>
Tümü
</Link>
</div>
<ul className="mt-4 space-y-1">
{otherSolutions.map((s) => (
<li key={s.slug}>
<Link
href={`/cozumler/${s.slug}`}
className="group flex items-center gap-3 rounded-lg px-2 py-2 text-sm transition hover:bg-[var(--navy-50)]"
>
<div className="flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--navy-50)] text-[var(--navy)] transition group-hover:bg-gradient-to-br group-hover:from-[var(--sky)] group-hover:to-purple-500 group-hover:text-white">
<Icon name={s.icon} className="size-4" />
</div>
<span className="flex-1 font-medium text-[var(--foreground)] group-hover:text-[var(--navy)]">
{s.title}
</span>
<ArrowRight className="size-3 text-[var(--muted)] opacity-0 transition group-hover:opacity-100" />
</Link>
</li>
))}
</ul>
</div>
)}
{/* Site analizi lead magnet */}
<div className="rounded-2xl border border-dashed border-[var(--border)] bg-white p-5">
<p className="text-xs font-semibold uppercase tracking-wider text-[var(--sky-600)]">
Ücretsiz fırsat
</p>
<h3 className="mt-1 text-sm font-bold text-[var(--navy)]">
Site analizi raporu
</h3>
<p className="mt-2 text-xs leading-relaxed text-[var(--muted)]">
Mevcut sitenizin SEO, hız ve dönüşüm performansını ücretsiz değerlendirelim.
</p>
<Link
href="/site-analizi"
className="mt-3 inline-flex items-center gap-1 text-xs font-semibold text-[var(--sky-600)] hover:text-[var(--navy)]"
>
Hemen başla
<ArrowRight className="size-3" />
</Link>
</div>
</aside>
);
}