diff --git a/src/app/dashboard/calendar/page.tsx b/src/app/dashboard/calendar/page.tsx index fee7964..154781c 100644 --- a/src/app/dashboard/calendar/page.tsx +++ b/src/app/dashboard/calendar/page.tsx @@ -25,16 +25,19 @@ export default async function CalendarPage() { .order('name') // Transform data for calendar - const events = reservations?.map(res => ({ - id: res.id, - title: `${res.customers?.full_name || 'Müşteri'} ${res.customers?.phone ? `(${res.customers.phone})` : ''}`, - start: new Date(res.start_time), - end: new Date(res.end_time), - resource: res, - })) || [] + const events = reservations?.map(res => { + const customer = Array.isArray(res.customers) ? res.customers[0] : res.customers + return { + id: res.id, + title: `${customer?.full_name || 'Müşteri'} ${customer?.phone ? `(${customer.phone})` : ''}`, + start: new Date(res.start_time), + end: new Date(res.end_time), + resource: res, + } + }) || [] return ( -
Giderlerinizi gruplandırmak için kategoriler oluşturun.
+Yeni bir harcama kaydı oluşturun.
+İşletme giderlerini takip edin.
+- Aktif rezervasyonlar -
-- Kayıtlı müşteri sayısı -
-Tahsil edilen ödemeler
+ İşletme giderleri +
++ Gelir - Gider +
++ Aktif rezervasyonlar +
+{customer?.full_name}
+{hall?.name}
+{event.customers?.full_name}
-{event.halls?.name}
+{format(new Date(event.start_time), 'd MMM yyyy', { locale: tr })}
+{format(new Date(event.start_time), 'HH:mm')}
{format(new Date(event.start_time), 'd MMM yyyy', { locale: tr })}
-{format(new Date(event.start_time), 'HH:mm')}
-{customer?.full_name} rezervasyon oluşturdu
++ {format(new Date(res.created_at), 'd MMM HH:mm', { locale: tr })} +
+{res.customers?.full_name} rezervasyon oluşturdu
-- {format(new Date(res.created_at), 'd MMM HH:mm', { locale: tr })} -
-Henüz işlem yok.
)} diff --git a/src/app/dashboard/reservations/[id]/actions.ts b/src/app/dashboard/reservations/[id]/actions.ts index 539a75e..4184ef2 100644 --- a/src/app/dashboard/reservations/[id]/actions.ts +++ b/src/app/dashboard/reservations/[id]/actions.ts @@ -32,6 +32,22 @@ export async function addPayment(reservationId: string, formData: FormData) { revalidatePath(`/dashboard/reservations/${reservationId}`) } +export async function deletePayment(id: string, reservationId: string) { + const supabase = await createClient() + const { error } = await supabase.from('payments').delete().eq('id', id) + if (error) throw new Error(error.message) + await logAction('delete_payment', 'payment', id, { reservationId }) + revalidatePath(`/dashboard/reservations/${reservationId}`) +} + +export async function cancelPayment(id: string, reservationId: string) { + const supabase = await createClient() + const { error } = await supabase.from('payments').update({ status: 'refunded' }).eq('id', id) + if (error) throw new Error(error.message) + await logAction('cancel_payment', 'payment', id, { reservationId }) + revalidatePath(`/dashboard/reservations/${reservationId}`) +} + export async function updateStatus(id: string, status: string) { const supabase = await createClient() @@ -42,6 +58,15 @@ export async function updateStatus(id: string, status: string) { if (error) throw new Error(error.message) + if (status === 'cancelled') { + const { error: paymentError } = await supabase + .from('payments') + .update({ status: 'refunded' }) + .eq('reservation_id', id) + + if (paymentError) console.error("Error cancelling payments:", paymentError) + } + await logAction('update_reservation_status', 'reservation', id, { status }) revalidatePath(`/dashboard/reservations/${id}`) @@ -61,3 +86,20 @@ export async function deleteReservation(id: string) { await logAction('delete_reservation', 'reservation', id) revalidatePath('/dashboard/reservations') } + +export async function updateReservationFinancials(id: string, packageId: string | null, price: number) { + const supabase = await createClient() + + const { error } = await supabase + .from('reservations') + .update({ + package_id: packageId, + price: price + }) + .eq('id', id) + + if (error) throw new Error(error.message) + + await logAction('update_reservation_financials', 'reservation', id, { packageId, price }) + revalidatePath(`/dashboard/reservations/${id}`) +} diff --git a/src/app/dashboard/reservations/[id]/financials-editor.tsx b/src/app/dashboard/reservations/[id]/financials-editor.tsx new file mode 100644 index 0000000..c5076b8 --- /dev/null +++ b/src/app/dashboard/reservations/[id]/financials-editor.tsx @@ -0,0 +1,122 @@ +'use client' + +import { useState } from "react" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Edit2 } from "lucide-react" +import { updateReservationFinancials } from "./actions" +import { toast } from "sonner" + +interface FinancialsEditorProps { + reservationId: string + currentPackageId: string | null + currentPrice: number + packages: any[] +} + +export function FinancialsEditor({ reservationId, currentPackageId, currentPrice, packages }: FinancialsEditorProps) { + const [open, setOpen] = useState(false) + const [loading, setLoading] = useState(false) + const [packageId, setPackageId] = useStateToplam Tutar
-₺{packagePrice}
-{reservation.packages?.name || "Paket Yok"}
+Toplam Tutar
+₺{effectivePrice}
+{reservation.packages?.name || "Özel Fiyat / Paket Yok"}
Ödenen
diff --git a/src/app/dashboard/reservations/[id]/payment-list.tsx b/src/app/dashboard/reservations/[id]/payment-list.tsx index 026e5a0..e49d194 100644 --- a/src/app/dashboard/reservations/[id]/payment-list.tsx +++ b/src/app/dashboard/reservations/[id]/payment-list.tsx @@ -14,10 +14,18 @@ import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { useState } from "react" -import { addPayment } from "./actions" +import { addPayment, deletePayment, cancelPayment } from "./actions" import { format } from "date-fns" import { tr } from "date-fns/locale" import { Badge } from "@/components/ui/badge" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { MoreVertical, Trash2, Ban } from "lucide-react" +import { toast } from "sonner" interface PaymentListProps { reservationId: string @@ -36,13 +44,34 @@ export function PaymentList({ reservationId, payments }: PaymentListProps) { try { await addPayment(reservationId, formData) setOpen(false) + toast.success("Ödeme eklendi") } catch (error) { - alert("Ödeme eklenirken hata oluştu") + toast.error("Ödeme eklenirken hata oluştu") } finally { setLoading(false) } } + const handleDelete = async (id: string) => { + if (!confirm("Bu ödemeyi silmek istediğinize emin misiniz?")) return + try { + await deletePayment(id, reservationId) + toast.success("Ödeme silindi") + } catch (error) { + toast.error("Silinirken hata oluştu") + } + } + + const handleCancel = async (id: string) => { + if (!confirm("Bu ödemeyi iptal/iade etmek istediğinize emin misiniz?")) return + try { + await cancelPayment(id, reservationId) + toast.success("Ödeme iptal edildi") + } catch (error) { + toast.error("İptal edilirken hata oluştu") + } + } + return (