Commit Graph

12 Commits

Author SHA1 Message Date
Ege Can Komur 304a344955 feat: KVKK/GDPR uyumlu cookie consent + Google Consent Mode v2
Yeni component'ler:
- CookieBanner (sağ alt banner + tam ekran ayarlar modal)
  - 'Tümünü kabul', 'Tümünü reddet', 'Ayarları yönet'
  - 4 kategori toggle: Zorunlu / Analitik / Reklam / Tercih
  - Zorunlu kategori her zaman açık (KVKK)
  - localStorage + cookie persistence (12 ay TTL)
  - Versionlı (CONSENT_VERSION=1) — şema değişince yeniden sorma
  - window.openCookieSettings() global helper (footer/policy sayfasından çağrılabilir)
- ConsentInit (Google Consent Mode v2 default deny)
  - beforeInteractive Script ile gtag default deny yüklenir
  - User onayladığında banner gtag('consent','update', ...) çağırır
  - seo_settings.gtm_id doluysa GTM injection (asenkron)
- CookieSettingsButton (politika sayfasında 'ayarları değiştir')

Yeni sayfa:
- /cerez-politikasi — KVKK uyumlu çerez politikası metni
  - 4 kategori detaylı açıklama + örnek çerez isimleri
  - KVKK Madde 11 kapsamındaki kullanıcı hakları
  - İletişim bilgileri site_settings'ten

Layout entegrasyonu:
- app/layout.tsx — ConsentInit head'e, CookieBanner body sonuna
- Footer'a 'Çerez Politikası' linki

Consent flag mapping (Consent Mode v2):
- Zorunlu → functionality_storage + security_storage (her zaman granted)
- Analitik → analytics_storage
- Reklam → ad_storage + ad_user_data + ad_personalization
- Tercih → personalization_storage

Önemli: Default state 'denied' — kullanıcı seçim yapmadan
hiçbir analytics/ads çerezi tetiklenmez. Google Ads Consent Mode v2 uyumlu.

31 route, public sayfalar static (1m revalidate).
2026-05-20 03:27:02 +03:00
Ege Can Komur 2373eccb17 fix: footer'dan gereksiz mt-24 boşluğunu kaldır
Anasayfada en alttaki 'Projenizi konuşalım' CTA section'ı koyu navy ile bitiyor,
footer da navy. Aradaki 96px beyaz alan görsel kopukluk yaratıyordu.

Diğer sayfalarda da son section'lar zaten kendi alt padding'ini veriyor (py-20),
ekstra footer margin'i gereksiz.
2026-05-20 03:16:29 +03:00
Ege Can Komur aa2b7280b6 feat: TR reklam trafiği için anasayfa CRO optimizasyonu
Yeni bölümler ve component'ler:
- WhatsAppFloat: sağ altta her sayfada görünen 'pulse' animasyonlu WhatsApp butonu
- MobileCtaBar: mobilde alt sabit bar — Ara / WhatsApp / Teklif Al üç buton
- TrustBand: hero altı 4 trust kartı (Google ★, proje sayısı, dönüş süresi, garanti)
  + Google rating + yorum sayısı satırı
- LogoCloud: müşteri logoları grayscale strip
- QuickLeadForm: ad + telefon iki alanlı inline mini form (anasayfada)
  - app/actions submitContact 'source' alanını destekliyor (quick lead → message zorunlu değil)
- WhyUs: 4 USP kartı (Hızlı teslim, Yerel destek, Modern tech, Satış sonrası)
- ProcessSteps: 4 adımlı 'nasıl çalışıyoruz' süreç akışı (numaralı timeline)

Schema (JSON-LD):
- OrganizationLd: LocalBusiness + Address + AggregateRating (Google review puanı/sayısı)
- ServiceLd: hizmet detay sayfaları için
- FaqLd: hizmet FAQ'leri için
- BreadcrumbLd, ArticleLd: hazır
Anasayfaya OrganizationLd ekli — Google Ads quality score + organic rich results.

Performans:
- REST GET çağrıları cache:'no-store' yerine next.revalidate=60 (ISR)
- Public sayfalar artık static rendering — LCP düşer
- Mutations ve session GET'ler hâlâ no-store

site_settings yeni alanları (panelden yönetilebilir):
- whatsapp_message (default WhatsApp opener)
- client_logos[] (logo URL listesi)
- trust_items[] (JSON: icon|value|label)
- why_us[] (JSON: icon, title, description)
- process_steps[] (JSON: title, description)
- lead_form_title, lead_form_description
- google_rating, google_review_count, google_review_url

Admin /admin/site formuna yeni 'Conversion / reklam optimizasyonu',
'Neden Biz?' ve 'Süreç adımları' bölümleri eklendi.

Mevcut anasayfa yapısı (üstten alta):
1. Hero
2. TrustBand (mini güven sinyalleri)
3. LogoCloud (varsa müşteri logoları)
4. Hızlı iletişim + QuickLeadForm (2 sütun: tel/WA CTA + mini form)
5. Hizmetler
6. WhyUs (Neden Biz?)
7. ProcessSteps (Nasıl çalışıyoruz?)
8. Projeler
9. Testimonials
10. CTA (Final + WhatsApp)
2026-05-20 03:08:05 +03:00
Ege Can Komur 1444aa3995 feat: anasayfa içeriği, iletişim ve sosyal medya yönetilebilir
Yeni site_settings tablosu (singleton, rowId='homepage'):
- Hero: badge, title, subtitle, 2 CTA (label+href), stats (JSON array)
- Section başlıkları: services/projects/testimonials eyebrow + title + description
- Alt CTA: title, description, button label+href
- Contact: phone (görünen + tel: ham), email, address, hafta içi/sonu saatleri
- Social: linkedin/instagram/twitter/facebook URL'leri
- Footer tagline

Mevcut hardcoded değerler seed edildi.

Admin:
- /admin/site sayfası eklendi (sidebar'a 'Site Ayarları' linki)
- Bölümlü tek form: Hero / Hizmetler / Projeler / Referanslar / Alt CTA / İletişim / Sosyal / Footer
- Stats için 'değer | etiket' satır formatı

Public bağlantılar:
- Hero component artık settings prop alıyor (fallback değerlerle)
- Anasayfa: tüm section başlıkları ve alt CTA settings'ten geliyor
- Header: telefon settings'ten
- Footer: tagline, adres, telefon, email, sosyal linkler settings'ten
  (sosyal link sadece dolu olanlar gösteriliyor)
- Footer'da hizmetler artık /hizmetler/[slug] detay sayfalarına bağlı
- İletişim sayfası: adres, telefon, email, saatler settings'ten

30 route üretiliyor.
2026-05-20 02:56:45 +03:00
Ege Can Komur c0da5ae8d3 feat: hizmet ve proje detay sayfaları + galeri sistemi
Yeni Appwrite kolonları:
- services: content (markdown), features[], faq[] (JSON-encoded), hero_image
- projects: gallery[], content (markdown), client_name, industry, duration, service_slug

Public sayfalar:
- /hizmetler/[slug]: hero + features checklist + markdown content + FAQ accordion
  + ilgili projeler (service_slug eşleşmesi)
- /projeler/[slug]: hero + meta tablosu (müşteri/sektör/süre/yıl) + kapak görseli
  + markdown vaka çalışması + lightbox galeri + diğer projeler

Yeni componentler:
- components/gallery.tsx: lightbox galeri (keyboard nav, prev/next, ESC kapat)
- components/faq-list.tsx: accordion FAQ (tek seferde tek açık)

Admin formları:
- Hizmet formu: hero_image, content (markdown), features (virgülle), FAQ
  (her blok '---' ile ayrılır, ilk satır soru, kalanı cevap)
- Proje formu: gallery (her satıra bir URL), content (markdown), client_name,
  industry, duration, service_slug (dropdown — hizmetlerden seçim)

Linkler:
- ServicesGrid kartları → /hizmetler/[slug]
- ProjectsGrid kartları → /projeler/[slug] (live_url butonu ayrı, target=_blank)

29 route üretiliyor.
2026-05-20 02:46:11 +03:00
Ege Can Komur edd0af76dc fix(auth): session secret'i response header'ından (X-Fallback-Cookies) oku
Sorun:
- createEmailPasswordSession response body'sinde 'secret' alanı boş/redacted geliyor
- Cookie'ye boş string yazılıyordu
- requireUser() çağrısında account.get() 401 dönüyor → login'e geri redirect
- Şifre doğru olsa bile bir döngüye giriyor

Çözüm:
- account.createEmailPasswordSession artık awRaw kullanıyor (Response objesi)
- extractSessionFromHeaders helper'ı X-Fallback-Cookies (JSON) veya
  Set-Cookie header'ından gerçek session secret'i parse ediyor
- Bu secret cookie'ye yazılıyor

Browser SDK kaynağında 'cookieFallback' tam olarak bu mantığı kullanıyor —
secret'i header'dan alıp localStorage'a yazıyor.
2026-05-20 02:35:27 +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 4096b3d87b fix: Node 26 uyumsuzluğunu çöz — node-appwrite -> appwrite SDK
Sorun:
- node-appwrite paketi 'node-fetch-native-with-agent' polyfill'i kullanıyor
- Node.js 26'nın undici implementation'ı ile uyumsuz
- 'fetch failed / InvalidArgumentError: invalid onError method' hatası
- Login dahil tüm Appwrite çağrıları başarısız

Çözüm:
- Tüm node-appwrite kullanımını browser SDK 'appwrite'a geçir
- Browser SDK native fetch kullanıyor, Node 26 uyumlu
- API key tabanlı admin client yerine session cookie tabanlı user client
- Public reads (read('any')): publicDB (auth'suz client)
- Admin CRUD: userDB(sessionSecret) (cookie'deki session)
- Storage upload doğrudan File objesi alıyor (InputFile.fromBuffer gerekmez)

Etkilenen dosyalar:
- lib/appwrite-server.ts: publicClient + sessionClient
- lib/auth.ts: requireSessionSecret eklendi
- lib/admin-actions.ts: tüm action'lar sessionClient kullanıyor
- app/actions.ts: publicDB
- lib/data.ts: publicDB
- app/admin/login/actions.ts: appwrite SDK
- app/admin/(protected)/page.tsx, medya/page.tsx: userDB/userStorage

End-to-end test edildi:
✓ Login (401 doğru hata)
✓ Public read (services)
✓ Anonim create (contact form)
✓ npm run build 23 route
2026-05-20 02:21:34 +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
Ege Can Komur 0f20309e4d docs: README'yi proje bilgileriyle güncelle 2026-05-20 01:52:46 +03:00
Ege Can Komur 3b3efafcc8 Kovak Yazılım kurumsal site — Next.js 16 + Appwrite
- Anasayfa, Hizmetler, Projeler, Hakkımızda, İletişim sayfaları
- Header/Footer, Hero, ServicesGrid, ProjectsGrid, ContactForm bileşenleri
- Appwrite TablesDB entegrasyonu (services, projects, contact_messages)
- Server Action ile iletişim formu (submitContact)
- Brand palette: navy #0F2C5C + sky #4DA3C7
- kovakyazilim.com'dan alınan logo public/logo.png
2026-05-20 01:52:27 +03:00
egecankomur 8a3a466087 Initial commit from Create Next App 2026-05-20 01:42:45 +03:00