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

294 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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.

# Frontend (Next.js) — Lead Form Entegrasyonu
## API Endpoint
```
POST /api/v1/leads
```
Auth yok, public endpoint. Rate limited.
---
## Request Body
```json
{
"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 | Açı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 | Açı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):
```json
{
"success": true,
"message": "Talebiniz alınmıştır. En kısa sürede sizinle iletişime geçeceğiz."
}
```
### Validasyon Hatası (422):
```json
{
"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ı)
```tsx
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
- [x] KVKK metnini okudum ve onaylıyorum (zorunlu checkbox)
- [ ] Kampanya ve duyurulardan haberdar olmak istiyorum
### 2. Danışmanlık Formu
```tsx
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
```tsx
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
```tsx
body: JSON.stringify({
name: formData.get('name'),
phone: formData.get('phone'),
source: 'duyuru',
kvkk_consent: true,
...utm,
})
```
### 5. Hero Form (Anasayfa)
```tsx
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:
```tsx
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):
```tsx
// 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.
```tsx
<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
```tsx
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
```ts
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;
}
```