# Boğaziçi Denizcilik - Backend (Laravel) & Admin Panel (Next.js) Gereksinim Dökümanı (v2)
Bu döküman, mevcut Next.js (Frontend) projenizin dinamik veri altyapısını bir **Laravel API**'sine bağlamak ve bu verileri yönetmek için tamamen ayrı bir **Next.js Admin Panel** geliştirmek üzere hazırlanmıştır.
*(v2 Güncellemesi: Gelişmiş Setting altyapısı, Pagination standartları, Modüler Page Builder API'leri, Soft Deletes, Caching, Audit Logs, Rate Limiting ve Çok Dilli (i18n) destek notları eklenmiştir.)*
> **Çok Dilli (i18n) Altyapı Notu:** Şimdilik v1 aşamasında tek dil (TR) olarak çıkılacaktır. Ancak v2+ versiyonları için i18n (Çoklu dil) planlanıyorsa, veritabanı tablolarında JSON field veya harici translations tablosu yaklaşımı değerlendirilecektir.
> **🤖 GitHub Copilot (VS Code) İçin Geliştirme Talimatı (Master Prompt):**
> *Laravel Herd ile kendi oluşturduğunuz projeyi VS Code'da açtıktan sonra, Copilot Chat'e (veya Cursor/Cline'a) şu mesajı yazmanız yeterlidir:*
>
> "Merhaba Copilot, bu projeyi **Laravel 12+** ile geliştireceğiz. Lütfen ana dizindeki **`backend_ve_admin_dokuman.md`** dosyasını dikkatlice baştan sona oku ve mimariyi kavra.
> Ardından şu işlemleri benim onayımı alarak **adım adım** kodlamaya başla:
> 1. Önce "1. Veritabanı Şeması" bölümündeki tüm tablolar için Laravel Migration, Model ve Factory dosyalarını oluştur. Önemli tablolarda SoftDeletes kullan. Bu adımı bitirince onayımı bekle.
> 2. Ardından "REST API" ve "Klasör Mimarisi" bölümüne geç. Kesinlikle spagetti controller yazma. Her modül için sırayla; `FormRequest`, `DTO`, `Action (Service)`, `Repository` ve en son `Controller` ile `api.php` rotalarını oluştur. Response standartlarına ve Caching kurallarına dikkat et.
> 3. Her modülü (Örn: Courses, Categories) tek tek kodla ve her modül bitiminde bana bilgi ver. Asla tüm projeyi tek seferde yazmaya çalışma."
---
## 1. Veritabanı Şeması (Laravel Modelleri & Migrations)
*(Güvenlik: Kaza eseri veri kayıplarını önlemek için yetki, kurs, kategori ve lead tablolarında `SoftDeletes` kullanılacaktır.)*
### 1.0. `users` & `roles` (Yetkilendirme / Auth)
- Laravel'in standart `users` tablosu. Admin panele giriş yapacak personeli temsil eder.
- Sisteme **Spatie Permission** paketi kurularak Role ve Yetki altyapısı tanımlanacaktır (Örn: `super-admin`, `editor`).
- `SoftDeletes` aktif olmalıdır.
### 1.1. `categories` (Eğitim Kategorileri)
- `id` (PK)
- `slug` (string, unique) - *Örn: guverte*
- `label` (string) - *Örn: Güverte Eğitimleri*
- `desc` (text, nullable)
- `image` (string, nullable) - *Sadece görsel path'i tutar*
- `meta_title` (string, nullable) - *SEO Title*
- `meta_description` (text, nullable) - *SEO Description*
- `created_at`, `updated_at`, `deleted_at` *(SoftDeletes)*
### 1.2. `courses` (Eğitimler/Kurslar)
- `id` (PK)
- `category_id` (FK -> categories.id)
- `slug` (string, unique)
- `title` (string)
- `sub` (string, nullable) - *Örn: STCW II/1*
- `desc` (text) - *Kısa açıklama*
- `long_desc` (longText) - *Detaylı açıklama*
- `duration` (string) - *Örn: 5 Gün*
- `students` (integer, default: 0) - *Kayıtlı öğrenci sayısı*
- `rating` (decimal: 2,1, default: 5.0)
- `badge` (string, nullable) - *Örn: Simülatör*
- `image` (string, nullable) - *Sadece path tutar*
- `price` (string, nullable)
- `includes` (json, nullable) - *Fiyata dahil olanlar listesi. Örn: `["Eğitim materyali", "Sertifika ücreti", "İkram"]`*
- `requirements` (json, nullable) - *Katılım koşulları/gereksinimler listesi. Örn: `["18 yaşını doldurmuş olmak", "Lise mezunu olmak"]`*
- `meta_title` (string, nullable) - *SEO Title*
- `meta_description` (text, nullable) - *SEO Description*
- `scope` (json, nullable) - *Eğitim kapsamı konu başlıkları dizisi. Örn: `["Ana makine sistemleri", "Yağlama ve soğutma sistemleri", "Yakıt sistemleri"]`*
- `standard` (string, nullable) - *Uyum standardı. Örn: `"STCW / IMO Uyumlu"`*
- `language` (string, nullable, default: `"Türkçe"`) - *Eğitim dili*
- `location` (string, nullable) - *Kursun varsayılan lokasyonu. Örn: `"Kadıköy, İstanbul"`*
- `created_at`, `updated_at`, `deleted_at` *(SoftDeletes)*
### 1.3. `course_schedules` (Takvim / Planlanan Eğitimler)
- `id` (PK)
- `course_id` (FK -> courses.id)
- `start_date` (date) - *Örn: 2026-02-24*
- `end_date` (date) - *Örn: 2026-02-28*
- `location` (string) - *Örn: Kadıköy veya Online*
- `quota` (integer) - *Toplam Kontenjan*
- `available_seats` (integer) - *Kalan Koltuk (Otomatik `quota - reserved_count` mantığıyla çalışmalı veya admin üzerinden manuel update edilmeli. Proje ilerleyişine göre netleşecek).*
- `is_urgent` (boolean, default: false) - *Sınırlı Kontenjan uyarısı*
- `created_at`, `updated_at`
### 1.4. `announcements` (Duyurular & Haberler)
- `id` (PK)
- `slug` (string, unique)
- `title` (string)
- `category` (string, enum) - *Tutarsızlığı önlemek için Enum kullanılmalı: `announcement` | `news` | `event`*
- `excerpt` (text)
- `content` (longText)
- `image` (string, nullable)
- `is_featured` (boolean, default: false)
- `meta_title` (string, nullable)
- `meta_description` (text, nullable)
- `published_at` (timestamp) - *Frontend'deki day/month yerine gerçek tarih tutulmalı*
- `created_at`, `updated_at`
### 1.5. `hero_slides` (Ana Sayfa Slider)
- `id` (PK)
- `label` (string) - *Örn: STCW Sertifikasyonu*
- `title` (string) - *Satır başı için \n destekli*
- `description` (text)
- `image` (string, nullable)
- `order` (integer, default: 0)
- `is_active` (boolean, default: true)
- `created_at`, `updated_at`
### 1.6. `leads` (Ön Kayıtlar / Form Başvuruları)
- `id` (PK)
- `name` (string)
- `phone` (string)
- `target_course` (string, nullable) - *İlgilenilen eğitim*
- `education_level` (string, nullable) - *Öğrenim durumu*
- `subject` (string, nullable) - *İlgilenilen konu (Danışmanlık formu için Örn: stcw, kaptanlik, belge, diger)*
- `message` (text, nullable) - *Ziyaretçinin ek mesajı (Danışmanlık formu için)*
- `status` (string, default: 'new') - *`new`, `contacted`, `enrolled`, `rejected`*
- `notes` (text, nullable) - *Admin notları*
- `is_read` (boolean, default: false) - *Admin panelde okunmamışları vurgulamak için*
- `source` (string) - *`hero_form` | `contact_form` | `consultation_form` | `whatsapp_widget`*
- `utm` (json, nullable) - *`utm_source`, `utm_campaign`, vb.*
- `consent_kvkk` (boolean, default: false)
- `consent_text_version` (string, nullable)
- `created_at`, `updated_at`, `deleted_at` *(SoftDeletes)*
### 1.7. `menus` (Dinamik Menü & Navigasyon Yönetimi)
Tüm site üst (Navbar) ve alt (Footer) bağlantılarının, Mega Menü içeriklerinin admin panelinden yönetilebilmesi için.
- `id` (PK)
- `location` (string) - *Örn: `header_main`, `footer_corporate`, `footer_education`, `footer_quicklinks`*
- `label` (string) - *Menüde Gözükecek Metin Örn: "Hakkımızda"*
- `url` (string) - *Örn: "/kurumsal/hakkimizda"*
- `type` (string, default: 'link') - *`link` (Normal Link) | `mega_menu_education` (Özel Hover Mega Menü) | `mega_menu_calendar` (Takvim Dropdown)*
- `parent_id` (integer, nullable) - *Alt menüler için (Self Referencing FK)*
- `order` (integer, default: 0) - *Sıralama*
- `is_active` (boolean, default: true)
- `created_at`, `updated_at`
### 1.8. `comments` (Eğitim ve Blog Yorumları / Soru-Cevap)
*Kullanıcıların üye olmadan, sadece Ad, Soyad ve Telefon numarası girerek Eğitimlere veya Duyurulara/Bloglara yorum yapabileceği ve adminlerin cevaplayabileceği sistem.*
- `id` (PK)
- `commentable_id` (integer) - *Hangi eğitime/duyuruya yapıldı? (Polymorphic Relation)*
- `commentable_type` (string) - *`App\\Models\\Course` veya `App\\Models\\Announcement`*
- `name_surname` (string) - *Kullanıcının Adı Soyadı*
- `phone` (string) - *Kullanıcının Telefon Numarası (Soru sorana ulaşmak gerekirse)*
- `body` (text) - *Yorum / Soru metni*
- `admin_reply` (text, nullable) - *Admin'in verdiği cevap (Önyüzde Admin Yanıtı olarak gözükecek)*
- `is_approved` (boolean, default: false) - *Admin onaylamadan sitede gözükmemeli*
- `created_at`, `updated_at`, `deleted_at` *(SoftDeletes)*
### 1.9. `faqs` (Sıkça Sorulan Sorular)
*Frontend'deki `/sss` sayfası ve anasayfadaki FAQ bileşeni için. Adminler soru-cevapları kategorili olarak yönetebilir.*
- `id` (PK)
- `category` (string) - *`egitimler` | `kayit` | `iletisim` (Tab bazlı filtreleme için)*
- `question` (text) - *Soru metni*
- `answer` (text) - *Cevap metni*
- `order` (integer, default: 0) - *Kategori içi sıralama*
- `is_active` (boolean, default: true) - *Pasif olanlar önyüzde gösterilmez*
- `created_at`, `updated_at`
### 1.10. `guide_cards` (Eğitim Rehberi Kartları)
*Frontend'deki `/egitim-rehberi` sayfasındaki kariyer yönlendirme kartları için. Admin panelden yönetilebilir.*
- `id` (PK)
- `title` (string) - *Örn: "Yeni Başlayanlar", "Yat Kaptanları"*
- `description` (text) - *Kart içeriği açıklaması*
- `icon` (string) - *Lucide icon adı (Örn: `anchor`, `compass`, `shield`, `briefcase`)*
- `color` (string) - *Gradient renk sınıfı (Örn: `from-blue-500 to-blue-700`)*
- `link` (string) - *Yönlendirme URL'i (Örn: `/egitimler/stcw`)*
- `order` (integer, default: 0) - *Sıralama*
- `is_active` (boolean, default: true)
- `created_at`, `updated_at`
### 1.11. `settings` (Sistem Ayarları)
*Admin panelinde otomatik tab/sekme yapısı kurmak ve public/private yalıtımı sağlamak için güçlendirilmiş yapı. Logo, sosyal medya linkleri gibi statik veriler buradan yönetilir.*
- `id` (PK)
- `group` (string) - *`general` | `contact` | `social` | `seo` | `forms` | `footer` | `guide`*
- `key` (string, unique)
- `value` (text/json, nullable)
- `type` (string) - *`text` | `textarea` | `image` | `boolean` | `json` | `richtext`*
- `is_public` (boolean, default: true) - *Public API'de görünsün mü? (Örn: `hero_form_email` gizli kalmalıdır).*
- `created_at`, `updated_at`
**Önerilen Settings Key Listesi (Otomatik Seeder ile Girecekler):**
- **Genel:** `site_name`, `site_logo`, `footer_logo`, `favicon`
- **Anasayfa İçerikleri (Sabit Alanlar):** `home_about_title`, `home_about_text`, `home_about_image_1`, `home_about_image_2`, `home_stats_students`, `home_stats_instructors`, `home_stats_courses` (Anasayfadaki "Biz Kimiz", "Kurum Hakkında" veya istatistik alanlarındaki resim/yazıların yönetimi için).
- **İletişim:** `contact_email`, `contact_cc_emails`, `phone_1`, `phone_2`, `whatsapp_phone`, `address`, `google_maps_embed_url`, `working_hours`
- **Sosyal Medya (Dinamik Logolar / Linkler):** `instagram_url`, `facebook_url`, `tiktok_url`, `x_url`, `youtube_url`, `linkedin_url` (Bu alanlar boş bırakılırsa önyüzde iconlar gizlenmelidir).
- **SEO:** `default_meta_title`, `default_meta_description`, `canonical_base`, `og_default_image`, `robots_indexing_enabled`
- **Formlar / KVKK / Kampanya:** `lead_notify_email`, `kvkk_text`, `privacy_policy_url`, `newsletter_title`, `newsletter_desc` (E-bülten ve "Sana özel kampanyalar" kutusundaki metinler).
- **Eğitim Rehberi:** `guide_page_title`, `guide_page_subtitle`, `guide_cta_title`, `guide_cta_text`, `guide_cta_button_text`, `guide_cta_button_url` (Eğitim Rehberi sayfasındaki başlık, alt metin ve CTA alanlarının yönetimi).
- **Danışmanlık:** `consultation_page_title`, `consultation_page_subtitle`, `consultation_form_title` (Danışmanlık sayfasının başlık ve açıklama alanlarının yönetimi).
---
## 2. Laravel REST API Uç Noktaları (Endpoints) & Standartları
**Cevap (Response) Format Standardı:**
Frontend tarafının hızlı ilerlemesi için tüm başarılı API listeleme talepleri paginate ve metadata içermeli, Laravel Resource üzerinden standartlaştırılmalıdır.
- Liste endpoint'leri: `{ "data": [], "meta": { "total": 0 }, "links": { } }`
- Tekil endpoint'ler: `{ "data": { } }`
**Parametrik Arama, Filtreleme, Sıralama:**
- `GET /api/v1/courses?category=guverte&search=stcw&sort=title&page=1`
- `GET /api/v1/announcements?category=news&featured=1&sort=-published_at&page=1`
### Public API (Frontend İçin - `api/v1/...`)
*(Performans için aktif olan sık kullanılan Public GET endpoint'leri **Laravel Cache / Redis** arkasında çalıştırılmalıdır. Veri Admin Panel'den güncellenince Cache Event ile temizlenmelidir.)*
- `GET /api/v1/settings` -> `is_public=true` olan ayarları döner.
- `GET /api/v1/hero-slides` -> Aktif slider içeriklerini sıralı getirir.
- `GET /api/v1/menus` -> Header ve Footer navigasyon ağacını hiyerarşik getirir.
- `GET /api/v1/categories` -> Kategorileri listeler.
- `GET /api/v1/courses` -> Eğitimleri listeler.
- `GET /api/v1/courses/{slug}` -> Tekil eğitim detayı.
- `GET /api/v1/schedules` -> Yaklaşan takvim eğitimlerini getirir. (Tarihe göre sıralı)
- `GET /api/v1/announcements` -> Duyuruları (featured olanlar dahil) getirir.
- `GET /api/v1/announcements/{slug}` -> Tekil duyuru detayı.
- `GET /api/v1/comments/{type}/{id}` -> Bir kursun veya blogun onaylanmış (`is_approved=true`) yorumlarını ve admin cevaplarını getirir.
- `POST /api/v1/comments` -> Ziyaretçiden yeni yorum/soru kaydı alır (Spam/Rate Limiting zorunlu).
- `GET /api/v1/faqs` -> Aktif SSS verilerini kategorili olarak getirir. `?category=egitimler` filtresi desteklenmeli.
- `GET /api/v1/guide-cards` -> Eğitim Rehberi kartlarını sıralı getirir.
- `GET /api/v1/pages/{slug}` -> Page builder bloklarını sırayla (`order_index`) getirir. *(Sadece `/page/` altındaki dinamik sayfalar için)*
- `POST /api/v1/leads` -> Ön kayıt formu alımı. `source` alanı ile form kaynağı (`hero_form`, `contact_form`, `consultation_form`) belirlenir. *(Spam koruması için IP bazlı Rate Limiting - Throttle uygulanmalıdır. Dakikada maks 2-3 gibi)*
- `GET /api/v1/sitemap-data` -> Frontend'in dinamik `sitemap.xml` oluşturması için tüm public slug'ları ve `updated_at` tarihlerini döner. *(Bkz: Bölüm 7.4)*
### Protected API (Admin Panel İçin - `api/admin/...`)
Tüm yetkili işlemler burada yalıtılmıştır.
- `POST /api/admin/login` -> Bearer token döndürür (Sanctum/Passport).
- `GET /api/admin/me` -> Giriş yapan admin detaylarını + Spatie Permission rollerini/izinlerini döner.
- `POST /api/admin/uploads` -> Multipart/form-data kabul eder. Standart resim yükleme ucudur. DB'ye URL değil **path** kaydeder. Response: `{ "path": "uploads/...", "url": "https://.../uploads/..." }`
- Modüller için tüm standart `POST` (Oluşturma), `PUT/PATCH` (Güncelleme), `DELETE` (Silme) uçları.
- Menü Yönetimi:
- `CRUD /api/admin/menus` -> Menü ekleme ve ağaç dökümü
- `POST /api/admin/menus/reorder` -> Sürükle-Bırak sonrası hiyerarşiyi (parent_id ve order) toplu güncelleme
- SSS (FAQ) Yönetimi:
- `CRUD /api/admin/faqs` -> Soru ekleme, düzenleme, silme, listeleme
- Eğitim Rehberi Kartları:
- `CRUD /api/admin/guide-cards` -> Kart ekleme, düzenleme, silme, listeleme
- Page Builder Admin uçları:
- `CRUD /api/admin/pages`
- `CRUD /api/admin/pages/{id}/blocks`
- `POST /api/admin/pages/{id}/blocks/reorder` -> Sürükle bırak ile sıra (`order_index`) güncelleme.
---
## 3. Laravel Katmanlı Mimari (Repository Pattern) Uygulama Standartları
Backend kodlanırken kesinlikle **Spagetti Controller** (Controller içine direkt `Course::create()` yazmak) kullanılmayacaktır. Tüm iş mantığı ve veritabanı sorguları şu katmanlara ayrılmalıdır:
**Önerilen Devasa (Enterprise) Klasör Mimarisi (`app/`):**
```text
app/
├── Http/
│ ├── Controllers/
│ │ └── Api/
│ │ └── CourseController.php # HTTP İsteğini alır, DTO'yu oluşturup Action'a yollar. Geriye Response döner.
│ ├── Requests/
│ │ └── StoreCourseRequest.php # Gelen verilerin validasyon zorunluluklarını (required, string) yapar.
│ └── Resources/
│ └── CourseResource.php # {YENİ} Frontend'e gidecek JSON formatını filtreler ve standartlaştırır (Presenter).
├── DTOs/
│ └── CourseData.php # Validasyonu geçmiş temiz veriyi, tiplendirilmiş Nesneye (DTO) dönüştürür.
├── Actions/ (veya Services/)
│ └── Course/
│ └── CreateCourseAction.php # Tüm "İş Mantığı". İndirim hesapla, Event fırlat, Repository'e yolla.
├── Repositories/
│ ├── Contracts/
│ │ └── CourseRepositoryInterface.php # Sınırlar ve Kurallar (Interface)
│ └── Eloquent/
│ └── CourseRepository.php # Veritabanı (DB) sorguları sadece buradadır (Course::create()).
├── Models/
│ └── Course.php # Tablo yapısı, İlişkiler (Relations)
├── Enums/
│ └── CourseStatus.php # Güvenli Sabitler
├── Events/
│ └── CourseCreatedEvent.php # Asenkron Olaylar (Decoupling için) -> Cache temizleme vb. burada ateşlenir.
├── Listeners/
│ └── NotifySubscribersListener.php # Olayı dinleyen arka plan işlemleri
├── Policies/
│ └── CoursePolicy.php # Yetki ve Rol kontrolleri (Örn: Yetkisiz kişi kurs silemez)
├── Exceptions/
│ └── CourseFullException.php # Domain'e özel hata sınıfları (400)
```
**Kusursuz (Ultimate) Veri Akış Yönü:**
`Route` ➔ `Middleware (Auth)` ➔ `Policy (Yetki)` ➔ `FormRequest (Validasyon)` ➔ `Controller` ➔ `DTO` ➔ `Action` ➔ `Repository (Interface)` ➔ `Model` ➔ `DB`
*(İşlem Başarılıysa)* ➔ `Action => Event Fırlatır / Activity Log Atılır`
*(Controller Çıkışı)* ➔ `API Resource (JSON Formatlama)` ➔ `Next.js FrontEnd`
**Audit Log / Kullanıcı İşlem Kayıtları Notu:**
Sisteme yetkili girişler yapılacağı için (Super Admin, Editor vs) veri güncellemelerini, silmeleri (SoftDelete edilen datalar) izlemek amacıyla projeye `spatie/laravel-activitylog` paketi kurulması, oluşan Transaction'ların tutulması önerilir.
---
## 4. Next.js Admin Panel Mimarisi Önerisi
Admin Paneli tamamen ayrı bir Next.js projesi olarak (Örn: `admin.bogazicidenizcilik.com` veya `localhost:3001` portunda) kurulmalıdır.
### **Mimari Prensip (Katmanlı Mimari - Layered Architecture):**
Kodların tek bir klasöre yığılmasını önlemek için Frontend kodları işlevselliğe göre ayrılmalıdır. Örnek `src/` mimarisi:
- `src/app/`: Sadece sayfalar (Routing) ve sayfa Layout'ları.
- `src/components/`: Ortak kullanılan UI elementleri (Button, Input, Table, **Ortak ImageUpload Bileşeni**).
- `src/features/`: Modül bazlı klasörleme (Örn: `features/courses/components`, `features/courses/api`, `features/courses/types`).
- `src/lib/`: Axios instance, yardımcı fonksiyonlar.
### Önerilen Klasör Dizilimi (`src/app/` Route Alanı):
```text
src/app/
├── (auth)/
│ └── login/page.tsx # Giriş ekranı (Kullanıcı Adı, Şifre -> Laravel Sanctum Token)
├── (dashboard)/
│ ├── layout.tsx # Sol Sidebar ve Üst Header kapsayıcısı (Role-based menu gösterimi)
│ ├── page.tsx # Dashboard Özeti (İstatistik kartları: Toplam Öğrenci, Yeni Formlar)
...
```
### Tüm Admin Modülleri ve Ekran Detayları
#### 4.1. Kategoriler (`/categories`)
- **`page.tsx`:** Kategori Tablosu (Resim, Kategori Adı, İşlemler (Düzenle/Sil)).
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- `label` *(Text Input)* - Kategori Adı
- `slug` *(Text Input)* - (Girilen isimden otomatik slug yaratılmalı)
- `desc` *(Textarea)* - Kısa Tanıtım
- `image` *(Upload Component)* - `POST /api/admin/uploads` tetikleyecek tek kullanımlık standart bileşen
- **SEO Alanı:** `meta_title`, `meta_description` *(Text Input)*
#### 4.2. Eğitimler (`/courses`)
- **`page.tsx`:** Eğitimler Tablosu (Kategorisine göre filtrelenebilir, Öğrenci Sayısı vs.).
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- **Genel Bilgiler:**
- `title`, `sub`, `category_id`, `price`, `duration`, `badge`
- **İçerik Editörü:**
- `desc` *(Textarea)*
- `longDesc` *(Rich Text Editor - CKEditor/Quill/Notion-stile Editor)*
- `image` *(Upload Component)*
- **Dinamik Diziler (Field Arrays / Repeaters):**
- `includes` *(Dynamic Input Array)* - "Fiyata Dahil Olanlar" (+)
- `requirements` *(Dynamic Input Array)* - "Kayıt Şartları" (+)
- **SEO Alanı:** `meta_title`, `meta_description` *(Text Input)*
#### 4.3. Eğitim Takvimi / Planlama (`/schedules`)
- **`page.tsx`:** Takvim Tablosu (Kurs Adı, Başlangıç, Bitiş, Kontenjan).
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- `course_id`, `start_date`, `end_date`, `location`, `quota`, `available_seats`
- `is_urgent` *(Switch / Checkbox)* - "Son 3 Gün" uyarı ateşleyicisi
#### 4.4. Duyurular ve Haberler (`/announcements`)
- **`page.tsx`:** Olayların Tablosu.
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- `title`, `category` (Seçim ile), `excerpt`, `content` (RTE), `image` (Upload), `meta_title`, `meta_description`
- `published_at` *(Date/Time Picker)* - İleri tarihli yayınlanma opsiyonu
- `is_featured` *(Switch)* - "Ana Sayfada Manşet Yap" onay kutusu
#### 4.5. Ön Kayıt Başvuruları (CRM) (`/leads`)
- **`page.tsx`:** Form başvuruları listesi. **`is_read = false` olan kayıtlar kalın (bold) veya fosforlu arka planla ayırt edici gösterilmelidir.**
- **`[id]/page.tsx` (Görüntüleme Müşteri Detayı):**
- Gelen veriler: *Adı, Telefon, Durumu, İlgilendiği Eğitim, Kaynak (Source), UTMEketleri, KVKK Onay Vrs.* (Salt Okunur - Read/Only).
- Yalnızca Tıklandığında backend'e PATCH isteği atılıp `is_read = true` yapılır.
- Admin işlemleri:
- `status` *(Select)* - (Yeni, Arandı, Kayıt Oldu, İptal)
- `notes` *(Textarea)* - Admin/Müşteri Temsilcisi iç notları. Form POST ile güncellenir.
#### 4.6. Menü ve Navigasyon Yönetimi (`/menus`)
- **`page.tsx`:** Menü lokasyonlarına (`header_main`, `footer_corporate`, `footer_education`, vb.) göre sekmeli (tab) bir liste. Her lokasyon için alt alta ağaç (tree) görünümlü kayıtlar. Sürükle-bırak (Drag & Drop) ile `POST /api/admin/menus/reorder` tetiklenerek sıralama ve parent/child ilişkisi hızlıca kurulabilmeli.
- **`[id]/page.tsx` (Ekleme / Düzenleme):**
- `location` *(Select)* - Header Ana Menü mü Yoksa Footer mı?
- `label` *(Text Input)* - "Eğitimler"
- `url` *(Text Input)* - "/egitimler"
- `type` *(Select)* - Normal Link mi (`link`), Eğitim Mega Menüsü mü (`mega_menu_education`), Takvim mi (`mega_menu_calendar`)
- `parent_id` *(Select)* - Bir ana menünün altına eklenecekse o ana menü seçilir.
- `is_active` *(Switch)*
#### 4.7. Yorum / Soru-Cevap Yönetimi (`/comments`)
- **`page.tsx`:** Kullanıcılardan (üye olmadan) Eğitim ve Bloglara gelen tüm soruların/yorumların düştüğü ekran. `is_approved = false` olanlar (yeni gelenler) belirgin şekilde listelenir.
- **`[id]/page.tsx` (Yorum Onay ve Yanıtlama):**
- Gelen veriler: *Adı Soyadı, Telefon Numarası, Yorum Yapılan İçerik (Kurs Adı vs), Yorum Metni* (Read-Only).
- `admin_reply` *(Textarea)* - Yorum/soruyu cevaplamak için adminin dolduracağı alan.
- `is_approved` *(Switch)* - Yorumun sitede herkes tarafından gözüküp gözükmeyeceği.
#### 4.8. SSS / Sıkça Sorulan Sorular Yönetimi (`/faqs`)
- **`page.tsx`:** FAQ Tablosu (Kategori, Soru, Aktif/Pasif durumu). Kategoriye göre filtrelenebilir.
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- `category` *(Select)* - `egitimler` | `kayit` | `iletisim`
- `question` *(Textarea)* - Soru metni
- `answer` *(Textarea / Rich Text)* - Cevap metni
- `order` *(Number Input)* - Kategori içi sıralama
- `is_active` *(Switch)* - Aktif/Pasif
#### 4.9. Eğitim Rehberi Kartları Yönetimi (`/guide-cards`)
- **`page.tsx`:** Rehber kartlarının listesi (Başlık, Icon, Link, Sıra).
- **`[id]/page.tsx` (Ekleme / Düzenleme Formu):**
- `title` *(Text Input)* - Kart başlığı (Örn: "Yeni Başlayanlar")
- `description` *(Textarea)* - Açıklama metni
- `icon` *(Select)* - Lucide icon seçimi (`anchor`, `compass`, `shield`, `briefcase` vb.)
- `color` *(Text Input / Color Picker)* - Gradient renk sınıfı
- `link` *(Text Input)* - Yönlendirme URL'i
- `order` *(Number Input)* - Sıralama
- `is_active` *(Switch)*
#### 4.10. Sitenin Genel Ayarları (`/settings`)
Bu tek bir sayfada çalışır:
- Sayfa ilk açıldığında `GET /api/admin/settings` ile tüm satırları çeker.
- `group` verisine göre yatay ya da dikey Tabs (Sekmeler) oluşturur (Genel, Anasayfa, İletişim, Sosyal Medya, SEO, Formlar, Eğitim Rehberi, Danışmanlık).
- **Anasayfa Sekmesi:** Anasayfadaki "Neden Biz", "Biz Kimiz", info/görsel alanlarındaki başlıklar (`home_about_title`), metinler (`home_about_text`) ve resimlerin (`home_about_image_1`) yönetimi.
- **Sosyal Medya Sekmesi:** Tüm hesapların (Instagram, Facebook, Tiktok, LinkedIn vb.) linkleri buraya girilir. Frontend, boş olmayan değerleri render eder.
- **Eğitim Rehberi Sekmesi:** Eğitim rehberi sayfasının başlık, alt metin ve CTA (Call to Action) alanlarının yönetimi.
- **Danışmanlık Sekmesi:** Danışmanlık sayfasının başlık ve açıklama metinleri.
- `type` verisine göre ekranda Text Input, Textarea veya Toggle Switch render eder. Kaydederken array olarak tek bir PATCH isteğinde sunucuya yollar.
---
## 5. Mevcut Frontend Projesi (Boğaziçi) Entegrasyon Adımları
Backend ve Admin Panel hazır olduğunda, mevcut statik yapınızda şu işlemler gerçekleştirilecektir:
1. **Çevresel Değişkenler:** `.env.local` içine `NEXT_PUBLIC_API_URL=http://api.bogazici.test/api/v1` eklenmeli. Yüklenen resimleri parse edebilmek için `NEXT_PUBLIC_ASSET_URL=http://api.bogazici.test` konulmalı.
2. **Data Fetching:**
- Statik `src/data/*.ts` dosyaları silinmeli.
- Tüm sayfalarda `fetch` kullanılarak (veya Axios) ISR yapısıyla veriler çekilmeli.
- *Örnek:* `const res = await fetch(\`\${process.env.NEXT_PUBLIC_API_URL}/courses\`, { next: { revalidate: 3600 } });`
3. **Form Gönderimi:** Hero'daki form submit edildiğinde veriler `POST /api/v1/leads` ucuna JSON olarak yollanmalı.
---
## 6. Dinamik Sayfalar İçin Headless Page Builder (`/page/` Rotası)
> **Kapsam Notu:** Page Builder sistemi **yalnızca** `/page/` rotası altında oluşturulan dinamik sayfalar için kullanılacaktır. Kurumsal sayfalar (`/kurumsal/hakkimizda`, `/kurumsal/vizyon-misyon`, vb.) ve `/danismanlik`, `/egitim-rehberi`, `/sss` gibi özel tasarımlı sayfalar frontend'de statik bileşenler olarak kalacak ve verilerini kendi API endpoint'lerinden veya `settings` tablosundan çekeceklerdir.
Admin panelden yeni landing page'ler, kampanya sayfaları veya özel içerik sayfaları oluşturmak için **Modüler Blok Sistemi** kullanılacaktır.
### Mevcut Frontend (Boğaziçi Denizcilik) Tarafında Okunması
**Örnek `src/app/page/[slug]/page.tsx` Kullanımı:**
```tsx
export default async function DynamicPage({ params }: { params: { slug: string } }) {
// 1. Laravel'den sayfanın aktif bloklarını çek
const page = await fetch(`.../api/v1/pages/${params.slug}`).then(r => r.json());
return (