376 lines
12 KiB
Markdown
376 lines
12 KiB
Markdown
# Admin Panel — Site Ayarları Modülü
|
||
|
||
## Genel Bakış
|
||
|
||
Backend'de `settings` tablosu güncellendi. Artık her ayarın **label** (Türkçe etiket) ve **order_index** (sıralama) alanları var. Ayarlar **9 gruba** ayrılmış durumda. Admin panelde her grup kendi sekmesi/sayfası olacak.
|
||
|
||
---
|
||
|
||
## API Endpoints
|
||
|
||
Tüm admin endpoint'leri `auth:sanctum` ile korunuyor. Base URL: `{API_URL}/api/admin`
|
||
|
||
| Method | Endpoint | Açıklama |
|
||
|--------|----------|----------|
|
||
| `GET` | `/admin/settings` | Tüm ayarları flat liste olarak getir |
|
||
| `GET` | `/admin/settings/group/{group}` | Tek grup ayarlarını getir |
|
||
| `PUT` | `/admin/settings` | Toplu güncelleme (dot notation) |
|
||
| `POST` | `/admin/settings/clear-cache` | Ayar cache'ini temizle |
|
||
|
||
---
|
||
|
||
## GET /admin/settings — Tüm Ayarlar
|
||
|
||
Her ayar şu formatta döner:
|
||
|
||
```json
|
||
{
|
||
"data": [
|
||
{
|
||
"id": 1,
|
||
"key": "site_name",
|
||
"value": "Boğaziçi Denizcilik Eğitim Kurumu",
|
||
"group": "general",
|
||
"type": "text",
|
||
"label": "Site Adı",
|
||
"order_index": 0
|
||
},
|
||
{
|
||
"id": 8,
|
||
"key": "announcement_bar_active",
|
||
"value": "true",
|
||
"group": "general",
|
||
"type": "boolean",
|
||
"label": "Üst Bar Aktif mi",
|
||
"order_index": 7
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**Frontend'de `group` bazında filtrele** → Her sekme/tab kendi grubunu gösterir.
|
||
|
||
---
|
||
|
||
## GET /admin/settings/group/{group} — Tek Grup
|
||
|
||
Sadece o grubun ayarlarını döner. `order_index` sıralı gelir.
|
||
|
||
Geçerli group değerleri:
|
||
- `general` — Genel site ayarları
|
||
- `contact` — İletişim bilgileri
|
||
- `maps` — Harita ayarları
|
||
- `social` — Sosyal medya linkleri
|
||
- `seo` — SEO, Open Graph, Twitter Card, doğrulama kodları
|
||
- `analytics` — Google Analytics, Tag Manager, Pixel ID'leri
|
||
- `header` — Navbar ve üst bar ayarları
|
||
- `footer` — Footer içerik ve stili
|
||
- `integrations` — SMTP, reCAPTCHA, bildirim ayarları
|
||
|
||
---
|
||
|
||
## PUT /admin/settings — Toplu Güncelleme
|
||
|
||
**Dot notation** formatında gönder: `{group}.{key}: value`
|
||
|
||
### Request Body:
|
||
|
||
```json
|
||
{
|
||
"settings": {
|
||
"general.site_name": "Yeni Site Adı",
|
||
"general.announcement_bar_active": "true",
|
||
"contact.phone_primary": "+90 555 123 45 67",
|
||
"social.instagram_url": "https://instagram.com/bogazicidenizcilik",
|
||
"header.cta_button_text": "Kayıt Ol",
|
||
"footer.copyright_text": "© 2026 Boğaziçi Denizcilik"
|
||
}
|
||
}
|
||
```
|
||
|
||
### Response:
|
||
```json
|
||
{ "message": "Ayarlar güncellendi." }
|
||
```
|
||
|
||
### Önemli:
|
||
- Sadece değişen ayarları gönderin, hepsini göndermenize gerek yok
|
||
- PUT sonrası backend otomatik olarak tüm cache'leri temizler
|
||
- Validation: `settings` required array, her value nullable string
|
||
|
||
---
|
||
|
||
## POST /admin/settings/clear-cache
|
||
|
||
Body gerekmez. Manuel cache temizleme butonu için.
|
||
|
||
```json
|
||
{ "message": "Ayar cache temizlendi." }
|
||
```
|
||
|
||
---
|
||
|
||
## Type'lara Göre Form Bileşenleri
|
||
|
||
Her ayarın `type` alanı, admin panelde hangi input bileşeninin kullanılacağını belirler:
|
||
|
||
| type | Bileşen | Açıklama |
|
||
|------|---------|----------|
|
||
| `text` | `<input type="text">` | Tek satır metin |
|
||
| `textarea` | `<textarea>` | Çok satır metin |
|
||
| `image` | Dosya yükleme + önizleme | Mevcut upload endpoint'i kullanılır (`POST /admin/uploads`) |
|
||
| `boolean` | Toggle/Switch | value `"true"` veya `"false"` string olarak saklanır |
|
||
| `url` | `<input type="url">` | URL formatı |
|
||
| `color` | Color picker | Hex renk kodu (#RRGGBB) |
|
||
| `richtext` | TipTap / zengin metin editör | HTML içerik |
|
||
| `json` | JSON editör | Yapısal veri |
|
||
|
||
### Boolean Değerler
|
||
Backend'de `value` her zaman **string** olarak saklanır. Boolean'lar `"true"` / `"false"` string:
|
||
```js
|
||
// Gönderirken
|
||
{ "settings": { "general.maintenance_mode": "false" } }
|
||
|
||
// Okurken
|
||
setting.value === "true" // → toggle ON
|
||
setting.value === "false" // → toggle OFF
|
||
```
|
||
|
||
### Image Alanları
|
||
1. Dosyayı `POST /admin/uploads` ile yükle → response'dan URL al
|
||
2. URL'yi settings update'e gönder:
|
||
```json
|
||
{ "settings": { "general.logo_light": "/storage/uploads/logo-white.png" } }
|
||
```
|
||
|
||
---
|
||
|
||
## Grup Detayları ve Alanlar
|
||
|
||
### general (13 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| site_name | text | Site Adı |
|
||
| site_tagline | text | Slogan |
|
||
| site_description | textarea | Kısa Site Açıklaması |
|
||
| logo_light | image | Logo — Açık Tema (beyaz navbar) |
|
||
| logo_dark | image | Logo — Koyu Tema (dark bg) |
|
||
| favicon | image | Favicon (32x32 PNG) |
|
||
| apple_touch_icon | image | Apple Touch Icon (180x180) |
|
||
| announcement_bar_active | boolean | Üst Bar Aktif mi |
|
||
| announcement_bar_text | text | Üst Bar Metni |
|
||
| announcement_bar_url | url | Üst Bar Linki |
|
||
| announcement_bar_bg_color | color | Üst Bar Arka Plan Rengi |
|
||
| maintenance_mode | boolean | Bakım Modu |
|
||
| maintenance_message | textarea | Bakım Modu Mesajı |
|
||
|
||
### contact (15 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| phone_primary | text | Ana Telefon |
|
||
| phone_secondary | text | İkinci Telefon |
|
||
| email_info | text | Bilgi E-postası |
|
||
| email_support | text | Destek E-postası |
|
||
| email_kayit | text | Kayıt E-postası |
|
||
| address_full | textarea | Tam Adres |
|
||
| address_short | text | Kısa Adres (navbar için) |
|
||
| district | text | İlçe |
|
||
| city | text | Şehir |
|
||
| postal_code | text | Posta Kodu |
|
||
| working_hours_weekday | text | Hafta İçi Saatleri |
|
||
| working_hours_saturday | text | Cumartesi Saatleri |
|
||
| working_hours_sunday | text | Pazar Saatleri |
|
||
| whatsapp_number | text | WhatsApp (+90 ile başlayan) |
|
||
| whatsapp_message | text | WhatsApp Varsayılan Mesaj |
|
||
|
||
### maps (6 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| google_maps_embed_url | textarea | Google Maps Embed URL (iframe src) |
|
||
| google_maps_place_url | url | Google Maps Profil Linki |
|
||
| google_maps_api_key | text | Google Maps API Key |
|
||
| latitude | text | Enlem |
|
||
| longitude | text | Boylam |
|
||
| map_zoom_level | text | Harita Zoom (1-20) |
|
||
|
||
> **Not:** `google_maps_api_key` admin endpoint'ten görünür ama public API'den filtrelenir.
|
||
|
||
### social (11 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| instagram_url | url | Instagram Profil URL |
|
||
| instagram_handle | text | Instagram Kullanıcı Adı (@siz) |
|
||
| facebook_url | url | Facebook Sayfası URL |
|
||
| facebook_page_id | text | Facebook Page ID |
|
||
| twitter_url | url | X (Twitter) Profil URL |
|
||
| twitter_handle | text | X Kullanıcı Adı (@siz) |
|
||
| youtube_url | url | YouTube Kanal URL |
|
||
| youtube_channel_id | text | YouTube Channel ID |
|
||
| linkedin_url | url | LinkedIn Sayfa URL |
|
||
| tiktok_url | url | TikTok Profil URL |
|
||
| pinterest_url | url | Pinterest URL |
|
||
|
||
### seo (23 alan)
|
||
|
||
**Temel SEO:**
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| meta_title_suffix | text | Title Eki |
|
||
| meta_title_separator | text | Ayraç Karakteri |
|
||
| default_meta_description | textarea | Varsayılan Meta Açıklama |
|
||
| default_meta_keywords | textarea | Varsayılan Keywords (virgülle) |
|
||
| robots | text | Robots |
|
||
| canonical_domain | url | Canonical Domain |
|
||
|
||
**Open Graph:**
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| og_title | text | OG Default Title |
|
||
| og_description | textarea | OG Default Description |
|
||
| og_image | image | OG Default Görsel (1200x630 px) |
|
||
| og_type | text | OG Type |
|
||
| og_locale | text | OG Locale |
|
||
| og_site_name | text | OG Site Name |
|
||
| facebook_app_id | text | Facebook App ID |
|
||
|
||
**Twitter / X Card:**
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| twitter_card_type | text | Card Tipi |
|
||
| twitter_site | text | Site @handle |
|
||
| twitter_creator | text | İçerik Sahibi @handle |
|
||
| twitter_title | text | Twitter Default Title |
|
||
| twitter_description | textarea | Twitter Default Description |
|
||
| twitter_image | image | Twitter Card Görseli (1200x600 px) |
|
||
|
||
**Doğrulama Kodları:**
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| google_site_verification | text | Google Search Console Kodu |
|
||
| bing_site_verification | text | Bing Webmaster Kodu |
|
||
| yandex_verification | text | Yandex Webmaster Kodu |
|
||
| pinterest_verification | text | Pinterest Doğrulama Kodu |
|
||
|
||
> **UI Önerisi:** SEO grubunu 4 alt sekmeye bölebilirsin: Temel SEO, Open Graph, Twitter Card, Doğrulama Kodları.
|
||
|
||
### analytics (10 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| google_analytics_id | text | Google Analytics 4 ID (G-XXXXXXXX) |
|
||
| google_tag_manager_id | text | Google Tag Manager ID (GTM-XXXXXXX) |
|
||
| google_ads_id | text | Google Ads Conversion ID |
|
||
| facebook_pixel_id | text | Meta (Facebook) Pixel ID |
|
||
| hotjar_id | text | Hotjar Site ID |
|
||
| clarity_id | text | Microsoft Clarity ID |
|
||
| tiktok_pixel_id | text | TikTok Pixel ID |
|
||
| crisp_website_id | text | Crisp Chat Website ID |
|
||
| custom_head_scripts | textarea | `<head>` içine özel script |
|
||
| custom_body_scripts | textarea | `<body>` sonuna özel script |
|
||
|
||
### header (9 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| navbar_style_default | text | Varsayılan Navbar Stili (transparent/white) |
|
||
| cta_button_text | text | Sağ Üst Buton Metni |
|
||
| cta_button_url | url | Sağ Üst Buton Linki |
|
||
| cta_button_color | color | Sağ Üst Buton Rengi |
|
||
| show_phone_topbar | boolean | Üst Bar'da Telefon Göster |
|
||
| show_email_topbar | boolean | Üst Bar'da E-posta Göster |
|
||
| show_address_topbar | boolean | Üst Bar'da Adres Göster |
|
||
| show_hours_topbar | boolean | Üst Bar'da Saat Göster |
|
||
| show_social_navbar | boolean | Navbar'da Sosyal Medya İkonları Göster |
|
||
|
||
### footer (8 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| footer_description | textarea | Footer Açıklaması |
|
||
| footer_logo | image | Footer Logo (varsa ayrı) |
|
||
| copyright_text | text | Copyright Metni |
|
||
| footer_address | textarea | Footer Adres |
|
||
| footer_phone | text | Footer Telefon |
|
||
| footer_email | text | Footer E-posta |
|
||
| footer_bg_color | color | Footer Arka Plan Rengi |
|
||
| show_social_footer | boolean | Footer'da Sosyal Medya Göster |
|
||
|
||
### integrations (10 alan)
|
||
| key | type | label |
|
||
|-----|------|-------|
|
||
| recaptcha_site_key | text | reCAPTCHA v3 Site Key |
|
||
| recaptcha_secret_key | text | reCAPTCHA v3 Secret Key |
|
||
| smtp_host | text | SMTP Host |
|
||
| smtp_port | text | SMTP Port |
|
||
| smtp_username | text | SMTP Kullanıcı Adı |
|
||
| smtp_password | text | SMTP Şifre |
|
||
| smtp_encryption | text | SMTP Şifreleme (tls/ssl) |
|
||
| smtp_from_name | text | Mail Gönderen Adı |
|
||
| smtp_from_email | text | Mail Gönderen Adresi |
|
||
| notification_emails | textarea | Bildirim E-postaları (virgülle) |
|
||
|
||
> **Not:** `integrations` grubundaki tüm ayarlar `is_public: false` — public API'den hiçbiri görünmez. `smtp_password` ve `*_secret_key` alanları password input olarak gösterilmeli.
|
||
|
||
---
|
||
|
||
## Önerilen Admin Panel Sayfa Yapısı
|
||
|
||
```
|
||
/admin/settings
|
||
├── Sidebar veya Tab Navigation
|
||
│ ├── Genel → general
|
||
│ ├── İletişim → contact
|
||
│ ├── Harita → maps
|
||
│ ├── Sosyal Medya → social
|
||
│ ├── SEO → seo (alt sekmeler: Temel, OG, Twitter, Doğrulama)
|
||
│ ├── Analitik → analytics
|
||
│ ├── Header → header
|
||
│ ├── Footer → footer
|
||
│ └── Entegrasyonlar → integrations
|
||
```
|
||
|
||
### Kaydet Akışı:
|
||
1. Kullanıcı bir gruptaki alanları düzenler
|
||
2. "Kaydet" butonuna basar
|
||
3. Sadece **değişen** alanlar `PUT /admin/settings` ile gönderilir
|
||
4. Başarılı response sonrası toast mesaj göster
|
||
5. Gerekirse `POST /admin/settings/clear-cache` butonu ekle (teknik kullanıcılar için)
|
||
|
||
### Dinamik Form Render:
|
||
`label` alanını form label olarak, `type` alanını input bileşeni seçmek için kullan. Backend'den gelen sıralama (`order_index`) form alanlarının sırası olarak kullanılabilir.
|
||
|
||
---
|
||
|
||
## Preview Sistemi (Page Builder)
|
||
|
||
Admin panelden sayfa blokları düzenlenirken önizleme özelliği:
|
||
|
||
| Method | Endpoint | Açıklama |
|
||
|--------|----------|----------|
|
||
| `POST` | `/admin/preview` | Önizleme token'ı oluştur |
|
||
| `DELETE` | `/admin/preview/{token}` | Önizlemeyi sil |
|
||
| `GET` | `/v1/preview/{token}` | Public — frontend fetch (auth yok) |
|
||
|
||
### POST /admin/preview
|
||
|
||
```json
|
||
// Request
|
||
{
|
||
"page_id": 1,
|
||
"blocks": [
|
||
{ "type": "hero", "content": { "title": "...", "description": "..." }, "order_index": 0 },
|
||
{ "type": "text", "content": { "_width": "half", "title": "...", "body": "..." }, "order_index": 1 }
|
||
]
|
||
}
|
||
|
||
// Response (201)
|
||
{
|
||
"token": "550e8400-e29b-41d4-a716-446655440000",
|
||
"preview_url": "http://localhost:3000/api/preview?token=550e8400...&slug=kalite-politikasi",
|
||
"expires_in": 600
|
||
}
|
||
```
|
||
|
||
### Kullanım:
|
||
1. Admin panelde "Önizle" butonuna bas → `POST /admin/preview`
|
||
2. Response'daki `preview_url`'yi yeni sekmede aç
|
||
3. Önizleme 10 dakika geçerli, sonra otomatik silinir
|
||
4. İsteğe bağlı: modal kapatılınca `DELETE /admin/preview/{token}` ile temizle
|