feat: TR reklam trafiği için anasayfa CRO optimizasyonu

Yeni bölümler ve component'ler:
- WhatsAppFloat: sağ altta her sayfada görünen 'pulse' animasyonlu WhatsApp butonu
- MobileCtaBar: mobilde alt sabit bar — Ara / WhatsApp / Teklif Al üç buton
- TrustBand: hero altı 4 trust kartı (Google ★, proje sayısı, dönüş süresi, garanti)
  + Google rating + yorum sayısı satırı
- LogoCloud: müşteri logoları grayscale strip
- QuickLeadForm: ad + telefon iki alanlı inline mini form (anasayfada)
  - app/actions submitContact 'source' alanını destekliyor (quick lead → message zorunlu değil)
- WhyUs: 4 USP kartı (Hızlı teslim, Yerel destek, Modern tech, Satış sonrası)
- ProcessSteps: 4 adımlı 'nasıl çalışıyoruz' süreç akışı (numaralı timeline)

Schema (JSON-LD):
- OrganizationLd: LocalBusiness + Address + AggregateRating (Google review puanı/sayısı)
- ServiceLd: hizmet detay sayfaları için
- FaqLd: hizmet FAQ'leri için
- BreadcrumbLd, ArticleLd: hazır
Anasayfaya OrganizationLd ekli — Google Ads quality score + organic rich results.

Performans:
- REST GET çağrıları cache:'no-store' yerine next.revalidate=60 (ISR)
- Public sayfalar artık static rendering — LCP düşer
- Mutations ve session GET'ler hâlâ no-store

site_settings yeni alanları (panelden yönetilebilir):
- whatsapp_message (default WhatsApp opener)
- client_logos[] (logo URL listesi)
- trust_items[] (JSON: icon|value|label)
- why_us[] (JSON: icon, title, description)
- process_steps[] (JSON: title, description)
- lead_form_title, lead_form_description
- google_rating, google_review_count, google_review_url

Admin /admin/site formuna yeni 'Conversion / reklam optimizasyonu',
'Neden Biz?' ve 'Süreç adımları' bölümleri eklendi.

Mevcut anasayfa yapısı (üstten alta):
1. Hero
2. TrustBand (mini güven sinyalleri)
3. LogoCloud (varsa müşteri logoları)
4. Hızlı iletişim + QuickLeadForm (2 sütun: tel/WA CTA + mini form)
5. Hizmetler
6. WhyUs (Neden Biz?)
7. ProcessSteps (Nasıl çalışıyoruz?)
8. Projeler
9. Testimonials
10. CTA (Final + WhatsApp)
This commit is contained in:
Ege Can Komur
2026-05-20 03:08:05 +03:00
parent 1444aa3995
commit aa2b7280b6
16 changed files with 1024 additions and 23 deletions
+22 -7
View File
@@ -19,14 +19,23 @@ export async function submitContact(
const phone = String(formData.get("phone") ?? "").trim();
const subject = String(formData.get("subject") ?? "").trim();
const message = String(formData.get("message") ?? "").trim();
const source = String(formData.get("source") ?? "").trim();
const errors: Record<string, string> = {};
if (!name) errors.name = "Ad zorunlu";
if (!email) errors.email = "E-posta zorunlu";
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email))
// E-posta YA DA telefon biri yeterli (quick lead form için)
if (!email && !phone) {
errors.email = "E-posta veya telefon zorunlu";
} else if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
errors.email = "Geçerli bir e-posta girin";
if (!message || message.length < 10)
}
// Tam form değilse message zorunlu değil
const isQuickLead = source.startsWith("quick");
if (!isQuickLead && (!message || message.length < 10)) {
errors.message = "Mesaj en az 10 karakter olmalı";
}
if (Object.keys(errors).length > 0) {
return { ok: false, message: "Lütfen form alanlarını kontrol edin", errors };
@@ -35,15 +44,21 @@ export async function submitContact(
try {
await tablesDB.createRow(DATABASE_ID, TABLES.contactMessages, ID.unique(), {
name,
email,
email: email || `${phone}@telefon.tr`, // email zorunlu — telefon-only ise placeholder
phone: phone || null,
subject: subject || null,
message,
subject: subject || (isQuickLead ? `Hızlı talep — ${source}` : null),
message:
message ||
(isQuickLead
? `Hızlı lead: ${name}${phone || email}. Geri arama bekleniyor.`
: ""),
status: "new",
});
return {
ok: true,
message: "Mesajınız iletildi. En kısa sürede dönüş yapacağız.",
message: isQuickLead
? "Talebiniz alındı. En kısa sürede sizi arayacağız."
: "Mesajınız iletildi. En kısa sürede dönüş yapacağız.",
};
} catch (err) {
const detail = err instanceof Error ? err.message : "Bilinmeyen hata";