Files
bogazici-api/prompts/frontend-leads.md
2026-03-27 10:41:54 +03:00

6.9 KiB
Raw Permalink Blame History

Frontend (Next.js) — Lead Form Entegrasyonu

API Endpoint

POST /api/v1/leads

Auth yok, public endpoint. Rate limited.


Request Body

{
  "name": "Ad Soyad",
  "phone": "+90 532 724 15 32",
  "email": "ornek@email.com",
  "source": "kurs_kayit",
  "target_course": "gemici-birlesik-egitimi",
  "education_level": "lise",
  "subject": "Eğitim başvurusu",
  "message": "Bilgi almak istiyorum",
  "kvkk_consent": true,
  "marketing_consent": false,
  "utm_source": "google",
  "utm_medium": "cpc",
  "utm_campaign": "denizcilik-2026"
}

Zorunlu Alanlar

Alan Tip ıklama
name string Ad Soyad (max 255)
phone string Telefon (max 20)
source string Form kaynağı (aşağıya bak)
kvkk_consent boolean Zorunlu, true olmalı — checkbox onaylatılmalı

Opsiyonel Alanlar

Alan Tip ıklama
email string E-posta
target_course string Hedef eğitim slug'ı
education_level string Eğitim seviyesi
subject string Konu
message string Mesaj
marketing_consent boolean Pazarlama onayı
utm_source string Google Analytics UTM
utm_medium string
utm_campaign string

Source Değerleri (Form Bazlı)

Her form kendi source değerini gönderir:

Form source Zorunlu Alanlar Opsiyonel Alanlar
Kurs ön kayıt kurs_kayit name, phone, kvkk_consent email, target_course, education_level, message
Danışmanlık danismanlik name, phone, kvkk_consent email, message, target_course
Duyuru sidebar duyuru name, phone, kvkk_consent email
İletişim iletisim name, phone, kvkk_consent email, subject, message
Hero form hero_form name, phone, kvkk_consent target_course
WhatsApp widget whatsapp_widget name, phone, kvkk_consent

Response

Başarılı (201):

{
  "success": true,
  "message": "Talebiniz alınmıştır. En kısa sürede sizinle iletişime geçeceğiz."
}

Validasyon Hatası (422):

{
  "message": "KVKK metnini onaylamanız gerekmektedir.",
  "errors": {
    "kvkk_consent": ["KVKK metnini onaylamanız gerekmektedir."],
    "name": ["Ad Soyad zorunludur."]
  }
}

Form Örnekleri

1. Kurs Ön Kayıt Formu (Eğitim Detay Sayfası)

async function submitKursKayit(formData: FormData, courseSlug: string) {
  const utm = getUTMParams(); // URL'den utm_source, utm_medium, utm_campaign

  const res = await fetch(`${API_URL}/api/v1/leads`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name: formData.get('name'),
      phone: formData.get('phone'),
      email: formData.get('email') || undefined,
      source: 'kurs_kayit',
      target_course: courseSlug,
      education_level: formData.get('education_level') || undefined,
      message: formData.get('message') || undefined,
      kvkk_consent: formData.get('kvkk') === 'on',
      marketing_consent: formData.get('marketing') === 'on',
      ...utm,
    }),
  });

  if (!res.ok) {
    const err = await res.json();
    throw new Error(err.message);
  }
  return res.json();
}

Form alanları:

  • Ad Soyad (zorunlu)
  • Telefon (zorunlu)
  • E-posta
  • Eğitim Seviyesi (select: ilkokul, ortaokul, lise, onlisans, lisans)
  • Mesaj
  • KVKK metnini okudum ve onaylıyorum (zorunlu checkbox)
  • Kampanya ve duyurulardan haberdar olmak istiyorum

2. Danışmanlık Formu

body: JSON.stringify({
  name: formData.get('name'),
  phone: formData.get('phone'),
  email: formData.get('email') || undefined,
  source: 'danismanlik',
  target_course: formData.get('interested_course') || undefined,
  message: formData.get('message') || undefined,
  kvkk_consent: true,
  ...utm,
})

3. İletişim Formu

body: JSON.stringify({
  name: formData.get('name'),
  phone: formData.get('phone'),
  email: formData.get('email') || undefined,
  source: 'iletisim',
  subject: formData.get('subject') || undefined,
  message: formData.get('message'),
  kvkk_consent: true,
  ...utm,
})

4. Duyuru Sidebar Mini Form

body: JSON.stringify({
  name: formData.get('name'),
  phone: formData.get('phone'),
  source: 'duyuru',
  kvkk_consent: true,
  ...utm,
})

5. Hero Form (Anasayfa)

body: JSON.stringify({
  name: formData.get('name'),
  phone: formData.get('phone'),
  source: 'hero_form',
  target_course: formData.get('course') || undefined,
  kvkk_consent: true,
  ...utm,
})

UTM Parametreleri

URL'deki UTM parametrelerini otomatik olarak form submit'e ekle:

function getUTMParams(): Record<string, string> {
  if (typeof window === 'undefined') return {};

  const params = new URLSearchParams(window.location.search);
  const utm: Record<string, string> = {};

  for (const key of ['utm_source', 'utm_medium', 'utm_campaign']) {
    const val = params.get(key);
    if (val) utm[key] = val;
  }
  return utm;
}

UTM değerleri sayfa boyunca korunmalı (cookie veya sessionStorage):

// Sayfa ilk yüklendiğinde
useEffect(() => {
  const utm = getUTMParams();
  if (Object.keys(utm).length > 0) {
    sessionStorage.setItem('utm', JSON.stringify(utm));
  }
}, []);

// Form submit'te
const utm = JSON.parse(sessionStorage.getItem('utm') || '{}');

KVKK Checkbox

Her formda KVKK onay checkbox'ı zorunlu. Backend kvkk_consent: true olmadan kabul etmez.

<label className="flex items-start gap-2">
  <input type="checkbox" name="kvkk" required />
  <span className="text-sm text-gray-600">
    <a href="/kvkk" target="_blank" className="underline">
      KVKK Aydınlatma Metni
    </a>'ni okudum ve onaylıyorum.
  </span>
</label>

Error Handling

try {
  const result = await submitLead(formData);
  // Başarılı — toast göster
  toast.success(result.message);
  form.reset();
} catch (error) {
  if (error.status === 422) {
    // Validasyon hataları — form alanlarının altında göster
    const { errors } = await error.json();
    setFieldErrors(errors);
  } else if (error.status === 429) {
    // Rate limit — çok fazla istek
    toast.error('Çok fazla istek gönderildi. Lütfen biraz bekleyin.');
  } else {
    toast.error('Bir hata oluştu. Lütfen tekrar deneyin.');
  }
}

TypeScript Tipi

interface LeadFormData {
  name: string;
  phone: string;
  email?: string;
  source: 'kurs_kayit' | 'danismanlik' | 'duyuru' | 'iletisim' | 'hero_form' | 'whatsapp_widget';
  target_course?: string;
  education_level?: string;
  subject?: string;
  message?: string;
  kvkk_consent: true; // Her zaman true olmalı
  marketing_consent?: boolean;
  utm_source?: string;
  utm_medium?: string;
  utm_campaign?: string;
}

interface LeadResponse {
  success: boolean;
  message: string;
}