diff --git a/COOLIFY.md b/COOLIFY.md
new file mode 100644
index 0000000..50b4bd6
--- /dev/null
+++ b/COOLIFY.md
@@ -0,0 +1,51 @@
+# Coolify ile Düğün Salonu Uygulaması Yayınlama Rehberi
+
+Bu proje **Next.js** tabanlıdır ve Coolify üzerinde **Nixpacks** kullanılarak kolayca yayınlanabilir.
+
+## 1. Hazırlık
+Projenizin kodlarının GitHub, GitLab veya Bitbucket üzerinde güncel olduğundan emin olun.
+
+## 2. Coolify Üzerinde Proje Oluşturma
+1. Coolify panelinize giriş yapın.
+2. **Projects** (Projeler) sekmesine gidin ve bir proje seçin (veya yeni oluşturun).
+3. **New** -> **Public Repository** (veya Private Repository) seçeneğini tıklayın.
+4. Git deposu bağlantısını yapıştırın (Örn: `https://github.com/kullanici/dugunsalonu`).
+5. **Check Repository** diyerek ilerleyin.
+
+## 3. Yapılandırma (Configuration)
+
+Coolify genellikle Next.js projesini otomatik algılar, ancak şu ayarları kontrol edin:
+
+* **Build Pack**: `Nixpacks` (Önerilen)
+* **Install Command**: `npm install`
+* **Build Command**: `npm run build`
+* **Start Command**: `npm run start`
+* **Port**: `3000`
+
+## 4. Ortam Değişkenleri (Environment Variables)
+Uygulamanın çalışması için `.env.local` dosyasındaki değerleri Coolify'a eklemeniz gerekir.
+
+1. Coolify'da projenizin **Environment Variables** (Secrets) sekmesine gidin.
+2. Aşağıdaki anahtarları ve değerlerini ekleyin:
+
+```env
+NEXT_PUBLIC_SUPABASE_URL=... (Supabase URL'iniz)
+NEXT_PUBLIC_SUPABASE_ANON_KEY=... (Supabase Anon Key'iniz)
+```
+
+> **Not:** Eğer varsa diğer `.env` değişkenlerinizi de eklemeyi unutmayın.
+
+## 5. Domain Ayarları
+1. **General** sekmesinde **Domains** bölümüne gidin.
+2. Uygulamanızın çalışacağı alanı adını (URL) girin. (Örn: `https://panel.dugunsalonu.com`)
+3. Domain sağlayıcınızdan (Cloudflare, GoDaddy vb.) `A` kaydını Coolify sunucunuzun IP adresine yönlendirin.
+
+## 6. Dağıtım (Deploy)
+1. Sağ üstteki **Deploy** butonuna basın.
+2. **Deployments** sekmesinden sürecin loglarını takip edebilirsiniz.
+3. "Build Success" mesajını gördüğünüzde uygulamanız yayında olacaktır.
+
+## Olası Sorunlar ve Çözümler
+* **Build Hatası:** Logları inceleyin. Genellikle bağımlılık (dependency) sorunları olabilir. `package-lock.json` dosyasının git reponuzda olduğundan emin olun.
+* **Resimler Görünmüyor:** `next.config.ts` dosyasındaki `images.remotePatterns` ayarının Supabase URL'nizi kapsadığından emin olun. (Bu projede `apiilker.edoysoft.com` zaten ekli).
+* **Sayfa Yenileyince 404:** Next.js SSR (Server Side Rendering) kullandığı için bu sorun genellikle yaşanmaz ancak Dockerfile kullanıyorsanız doğru yapılandırıldığından emin olun. Nixpacks bu ayarları otomatik yapar.
diff --git a/src/app/dashboard/expenses/page.tsx b/src/app/dashboard/expenses/page.tsx
index a37885c..c2b279d 100644
--- a/src/app/dashboard/expenses/page.tsx
+++ b/src/app/dashboard/expenses/page.tsx
@@ -6,6 +6,7 @@ import {
Table,
TableBody,
TableCell,
+ TableFooter,
TableHead,
TableHeader,
TableRow,
@@ -83,6 +84,16 @@ export default async function ExpensesPage() {
))
)}
+
+
+ Toplam Gider:
+
+ - {new Intl.NumberFormat('tr-TR', { style: 'currency', currency: 'TRY' }).format(
+ expenses?.reduce((sum, expense) => sum + Number(expense.amount), 0) || 0
+ )}
+
+
+
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index c7404ec..7598b4e 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -72,39 +72,43 @@ export default async function DashboardPage() {
diff --git a/src/app/dashboard/payments/page.tsx b/src/app/dashboard/payments/page.tsx
new file mode 100644
index 0000000..9ec8784
--- /dev/null
+++ b/src/app/dashboard/payments/page.tsx
@@ -0,0 +1,131 @@
+import { createClient } from "@/lib/supabase/server"
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableFooter,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table"
+import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
+import { format } from "date-fns"
+import { tr } from "date-fns/locale"
+import { Badge } from "@/components/ui/badge"
+
+export default async function PaymentsPage() {
+ const supabase = await createClient()
+
+ const { data: payments } = await supabase
+ .from('payments')
+ .select(`
+ id,
+ amount,
+ created_at,
+ payment_method,
+ payment_type,
+ status,
+ reservations (
+ id,
+ start_time,
+ status,
+ customers (full_name)
+ )
+ `)
+ .order('created_at', { ascending: false })
+
+ const getStatusBadge = (status: string) => {
+ switch (status) {
+ case 'paid': return
Ödendi
+ case 'pending': return
Bekliyor
+ case 'refunded': return
İade
+ case 'confirmed': return
Onaylandı
+ case 'cancelled': return
İptal
+ case 'completed': return
Tamamlandı
+ default: return
{status}
+ }
+ }
+
+ const getCustomerName = (reservation: any) => {
+ if (!reservation) return "-"
+ const res = Array.isArray(reservation) ? reservation[0] : reservation
+ const customer = res?.customers
+ const cust = Array.isArray(customer) ? customer[0] : customer
+ return cust?.full_name || "-"
+ }
+
+ const getReservationDate = (reservation: any) => {
+ if (!reservation) return "-"
+ const res = Array.isArray(reservation) ? reservation[0] : reservation
+ return res?.start_time ? format(new Date(res.start_time), 'd MMM yyyy', { locale: tr }) : "-"
+ }
+
+ const getReservationStatus = (reservation: any) => {
+ if (!reservation) return "-"
+ const res = Array.isArray(reservation) ? reservation[0] : reservation
+ return res?.status || "-"
+ }
+
+ return (
+
+
+
Ödemeler
+
Tüm alınan ödemelerin listesi.
+
+
+
+
+
+
+ Tarih
+ Müşteri
+ Rez. Tarihi
+ Tutar
+ Ödeme Türü
+ Ödeme Yöntemi
+ Ödeme Durumu
+ Rez. Durumu
+
+
+
+ {payments?.length === 0 ? (
+
+
+ Henüz ödeme kaydı yok.
+
+
+ ) : (
+ payments?.map((payment: any) => (
+
+
+ {format(new Date(payment.created_at), 'd MMMM yyyy HH:mm', { locale: tr })}
+
+ {getCustomerName(payment.reservations)}
+ {getReservationDate(payment.reservations)}
+ ₺{Number(payment.amount).toLocaleString('tr-TR')}
+
+ {payment.payment_type === 'deposit' ? 'Kapora' :
+ payment.payment_type === 'full' ? 'Tam Ödeme' :
+ payment.payment_type === 'remaining' ? 'Kalan' : payment.payment_type}
+
+ {payment.payment_method === 'credit_card' ? 'Kredi Kartı' : payment.payment_method === 'cash' ? 'Nakit' : 'Havale/EFT'}
+ {getStatusBadge(payment.status)}
+ {getStatusBadge(getReservationStatus(payment.reservations))}
+
+ ))
+ )}
+
+
+
+ Toplam:
+
+ ₺{payments?.reduce((sum: number, p: any) => sum + Number(p.amount), 0).toLocaleString('tr-TR')}
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/app/dashboard/reservations/page.tsx b/src/app/dashboard/reservations/page.tsx
index 8c099e1..5185b22 100644
--- a/src/app/dashboard/reservations/page.tsx
+++ b/src/app/dashboard/reservations/page.tsx
@@ -29,7 +29,7 @@ export default async function ReservationsPage() {
customers (full_name),
packages (name, price)
`)
- .order('start_time', { ascending: true })
+ .order('created_at', { ascending: false })
const getStatusBadge = (status: string) => {
switch (status) {