f833d429fc
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.
142 lines
4.7 KiB
Markdown
142 lines
4.7 KiB
Markdown
# 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
|
||
```
|