# Kovak Yazılım — Kurumsal Site + Admin Panel Next.js 16 + TypeScript + Tailwind v4 + Appwrite ile geliştirilmiş kurumsal site ve içerik yönetim paneli. ## Teknoloji - **Framework:** Next.js 16 (App Router, Turbopack, React 19) - **Stil:** Tailwind CSS v4 - **Backend:** Appwrite (TablesDB + Storage + Auth) — `https://db.kovaksoft.com` - **İçerik:** Markdown (marked.js) - **İkonlar:** lucide-react + inline SVG - **Form:** React Server Actions + `useActionState` ## Kurulum ```bash npm install cp .env.example .env.local # .env.local içine APPWRITE_API_KEY'i Appwrite Console'dan oluşturup ekle npm run dev ``` Site: Admin: ## İlk Admin Kullanıcısı 1. Appwrite Console → Auth → Users → Create User 2. Email + şifre belirle 3. `/admin/login` üzerinden giriş yap ## Appwrite Yapılandırması **Project ID:** `69f27b51000a5bee46ce` **Database ID:** `kovak-yazilim-db` **Bucket ID:** `kovak-yazilim-media` ### Tablolar | Tablo | İçerik | |---|---| | `services` | Hizmet kartları (slug, title, description, icon, order, featured) | | `projects` | Referans projeler (slug, title, description, image_url, live_url, category, technologies[], year, featured) | | `blog_posts` | Blog yazıları (slug, title, excerpt, content, cover_image, author, status, published_at, tags[], seo_*) | | `testimonials` | Müşteri yorumları (name, role, company, message, rating, image_url, order, featured) | | `seo_pages` | Sayfa bazlı SEO override (path, title, description, og_image, canonical, noindex) | | `seo_settings` | Global SEO ayarları (singleton — rowId: `global`) | | `contact_messages` | İletişim formu kayıtları (anonim create, users read/update/delete) | ### Storage `kovak-yazilim-media` — 10 MB max, image-only (jpg/png/webp/gif/svg/avif). Public read. ### API Key Appwrite Console → Settings → API Keys → Create Scopes: `databases.read`, `tables.read`, `rows.read`, `rows.write`, `files.read`, `files.write`, `users.read` ## Admin Paneli `/admin` altında: - **Pano** (`/admin`) — Sayım kartları + hızlı aksiyonlar - **Blog** (`/admin/blog`) — Yazı CRUD, draft/published durumu, markdown editor - **Hizmetler** (`/admin/hizmetler`) — Hizmet CRUD, lucide ikon seçici - **Projeler** (`/admin/projeler`) — Portfolyo CRUD - **Referanslar** (`/admin/referanslar`) — Müşteri yorumları - **SEO** (`/admin/seo`) — Global meta + sayfa bazlı override - **Mesajlar** (`/admin/iletisim`) — Form inbox, status (new/read/replied/archived) - **Medya** (`/admin/medya`) — Appwrite Storage browser, upload/delete ### Auth Akışı `lib/auth.ts` → `getCurrentUser()` & `requireUser()` Login → `account.createEmailPasswordSession` → session secret HTTP-only cookie (`kovak_session`) Admin layout (`app/admin/(protected)/layout.tsx`) `requireUser()` çağrısı yapar — yetkisiz giriş `/admin/login`'e redirect. ## SEO Sistemi `lib/seo.ts` → `buildMetadata(path, fallback)` Sıralama (override öncelikli): 1. `seo_pages` tablosunda o path için kayıt varsa → onun title/description/og_image kullanılır 2. Yoksa sayfanın kendi fallback `Metadata` objesi 3. O da yoksa `seo_settings` (global) 4. O da yoksa `lib/site-config.ts` ## Yapı ``` app/ (site)/ # Public site (Header + Footer ortak) page.tsx # Anasayfa hizmetler/ # /hizmetler projeler/ # /projeler blog/ # /blog, /blog/[slug] hakkimizda/ iletisim/ admin/ login/ # /admin/login (auth dışı) (protected)/ # requireUser() ile korunan grup page.tsx # /admin blog/ hizmetler/ projeler/ referanslar/ seo/ iletisim/ medya/ actions.ts # Public Server Action: submitContact layout.tsx # Root layout (html/body) components/ admin/ # Sidebar, topbar, form helpers, delete button header.tsx, footer.tsx hero.tsx, services-grid.tsx, projects-grid.tsx, testimonials.tsx contact-form.tsx lib/ appwrite.ts # Browser client appwrite-server.ts # adminClient (API key) + sessionClient (cookie) auth.ts # Session helpers admin-actions.ts # Tüm CRUD server actions (gate() ile auth check) data.ts # listX / getX sorguları seo.ts # buildMetadata site-config.ts # Marka + fallback değerler types.ts # Row tipleri public/logo.png # Logo ``` ## Build ```bash npm run build # 23 route, public sayfalar static, admin dynamic npm start ``` ## Gitea Remote ```bash git remote add origin ssh://git@git.kovaksoft.com:2222/kovakmedya/kovakyazilim.git git push -u origin main ```