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

376 lines
12 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.

# 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