Files
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

142 lines
4.7 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.
# 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: <http://localhost:3000>
Admin: <http://localhost:3000/admin/login>
## İ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
```