4 Commits

Author SHA1 Message Date
egecankomur d49c9aa225 feat: SEO altyapısı + admin editör/favicon/menü düzeltmeleri
Admin & site:
- @tailwindcss/typography ekle → editör ve yayın içeriği prose stilleriyle düzgün render
- Favicon: logo.png'den kare app/icon.png + apple-icon.png, varsayılan favicon.ico kaldırıldı
- SEO keyword: seo_settings.default_keywords + seo_pages.keywords + buildMetadata birleştirme
- Menü düzeni admin'den yönetilebilir (site_settings.nav_items, /admin/menu, header & mobile-menu refactor)

SEO:
- app/sitemap.ts (statik + blog/hizmet/çözüm/proje/sektör dinamik)
- app/robots.ts (sitemap ref + /admin,/api disallow)
- app/llms.txt/route.ts (AI/LLM rehberi)
- BlogPosting/Service/FAQ/Article JSON-LD wire (json-ld bileşenleri bağlandı)
- buildMetadata: blog/proje OG görseli + type article + keywords birleştirme düzeltmesi
- blog tags → keyword
2026-06-04 07:15:18 +03:00
Ege Can Komur dbc55e7527 feat: MediaPicker — sürükle-bırak + progress bar + kütüphane modal
Mevcut sorun:
- Her görsel için medya sayfasına git, yükle, URL kopyala, forma yapıştır → 4 adım
- Sürükle-bırak yok, progress yok, hangi dosyanın yüklendiği belirsiz

Çözüm: MediaPicker component (tek/çoklu mode)

API route'ları:
- POST /api/admin/media/upload — session auth + Appwrite Storage upload
- GET /api/admin/media/list — kütüphane modal için dosya listesi

Component özellikleri:
- Sürükle-bırak drop zone (hover state ile)
- Multiple file upload (çoklu mode)
- XHR ile gerçek progress bar (%) — Server Action ile alınamazdı
- Görsel preview (single: aspect-video, multiple: aspect-square grid)
- Hover'da × ile kaldırma
- Multiple mode'da sırasını değiştirme
- 'Kütüphaneden seç' modal — daha önce yüklenmiş görselleri grid'de göster, tıklayınca seç
- Error handling (dosya boyutu, ağ hatası vb.)
- Başarılı yüklemeyi 2 saniye gösterip kaybetme

Form alanları → MediaPicker (URL field'ları kaldırıldı):
- Blog: cover_image, seo_image
- Hizmet: hero_image
- Proje: image_url (kapak), gallery (çoklu)
- Referans: image_url
- Sektör: hero_image
- Ekip: photo_url
- SEO sayfa: og_image
- SEO global: default_og_image
- Site Settings: client_logos (çoklu)

Backward compat: form data formatı aynı kalıyor — hidden input ile URL satır satır.
admin-actions değişmedi. URL elle yapıştırmak hala mümkün (kütüphaneden URL kopyala).
2026-05-20 04:11:41 +03:00
Ege Can Komur 7eb0c1acc2 fix(auth): SDK'yı kaldırıp ince REST katmanına geç (lib/appwrite-rest.ts)
Sorun:
- node-appwrite v20-25 hepsi Node 26'da bozuk (node-fetch-native-with-agent polyfill)
- appwrite browser SDK Server Action context'inde 'unexpected response' veriyor
  (büyük olasılıkla browser-only global'ları kontrol ederken)

Çözüm:
- Tüm Appwrite SDK'larını sil (appwrite + node-appwrite)
- lib/appwrite-rest.ts: native fetch üzerinde ~250 satırlık ince REST wrapper
  - account: createEmailPasswordSession, get, deleteSession
  - tablesDB: listRows, getRow, createRow, updateRow, deleteRow
  - storage: listFiles, createFile, deleteFile, fileViewUrl
  - Q helpers: equal, orderAsc/Desc, limit, offset
  - AppwriteError class
- Session secret cookie tabanlı auth korundu (isletmem-kovakcrm'deki desen)
- Tüm CRUD action ve query'ler REST katmanına bağlandı

End-to-end test edildi:
✓ Login (proper 401 hata mesajları, başarılı durumda redirect)
✓ Public read (services, blog, testimonials)
✓ Anonim create (contact form)
✓ Build (24 route)
✓ Sıfır SDK bağımlılığı — Node 26 sorunu yok
2026-05-20 02:29:19 +03:00
Ege Can Komur f833d429fc feat: admin paneli + blog + testimonials + SEO yöneticisi
Backend altyapısı:
- 4 yeni Appwrite tablosu: blog_posts, testimonials, seo_pages, seo_settings
- Appwrite Storage bucket: kovak-yazilim-media (görsel yüklemeleri)
- Appwrite Auth ile session cookie tabanlı koruma

Admin paneli (/admin):
- Login akışı (email/password) + protected layout
- Dashboard: sayım kartları + hızlı aksiyonlar
- Blog CRUD: markdown content, kapak görseli, draft/published, SEO alanları
- Services CRUD: lucide ikon seçici
- Projects CRUD: teknoloji etiketleri, live URL
- Testimonials CRUD: puanlama
- SEO yöneticisi: global ayarlar + sayfa bazlı override
- Mesaj inbox: status filtreleme + güncelleme
- Medya kütüphanesi: Appwrite Storage upload/delete

Public:
- /blog ve /blog/[slug] sayfaları (markdown render)
- Anasayfaya Testimonials bölümü
- Tüm public sayfalarda generateMetadata + seo_pages override
- Header'a Blog linki

Route yapısı:
- app/(site)/ — public site, Header/Footer ortak
- app/admin/login — auth dışı
- app/admin/(protected)/ — requireUser() korumalı

23 route üretiliyor, public static, admin dynamic.
2026-05-20 02:13:09 +03:00