update deploy

This commit is contained in:
bulut
2026-03-27 10:41:54 +03:00
parent 69d19c0176
commit 6f6448aa06
422 changed files with 37956 additions and 0 deletions

375
prompts/admin-settings.md Normal file
View File

@@ -0,0 +1,375 @@
# 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