sms entegrasyonu ve ana sayfa işlemleri

This commit is contained in:
2026-01-26 00:19:09 +03:00
parent 1e1baa84ff
commit 5c34df0f09
19 changed files with 1018 additions and 17 deletions

View File

@@ -0,0 +1,76 @@
import { getCustomers, deleteCustomer } from "@/lib/customers/actions"
import { CustomerForm } from "@/components/dashboard/customer-form"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import { Trash, Edit } from "lucide-react"
export default async function CustomersPage() {
const { data: customers } = await getCustomers()
return (
<div className="flex-1 space-y-4 p-8 pt-6">
<div className="flex items-center justify-between space-y-2">
<h2 className="text-3xl font-bold tracking-tight">Müşteriler</h2>
<div className="flex items-center space-x-2">
<CustomerForm />
</div>
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead>Ad Soyad</TableHead>
<TableHead>E-Posta</TableHead>
<TableHead>Telefon</TableHead>
<TableHead>Adres</TableHead>
<TableHead className="w-[100px]">İşlemler</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{customers?.length === 0 && (
<TableRow>
<TableCell colSpan={5} className="h-24 text-center">
Henüz müşteri bulunmuyor.
</TableCell>
</TableRow>
)}
{customers?.map((customer) => (
<TableRow key={customer.id}>
<TableCell className="font-medium">{customer.full_name}</TableCell>
<TableCell>{customer.email || "-"}</TableCell>
<TableCell>{customer.phone || "-"}</TableCell>
<TableCell className="truncate max-w-[200px]">{customer.address || "-"}</TableCell>
<TableCell className="flex items-center gap-2">
<CustomerForm
customer={customer}
trigger={
<Button variant="ghost" size="icon" className="h-8 w-8">
<Edit className="h-4 w-4" />
</Button>
}
/>
<form action={async () => {
'use server'
await deleteCustomer(customer.id)
}}>
<Button variant="ghost" size="icon" className="h-8 w-8 text-destructive">
<Trash className="h-4 w-4" />
</Button>
</form>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
)
}

View File

@@ -28,6 +28,15 @@ export default async function SettingsPage() {
{ key: 'site_title', value: 'ParaKasa', type: 'text', section: 'general' },
{ key: 'site_description', value: '', type: 'long_text', section: 'general' },
{ key: 'site_logo', value: '', type: 'image_url', section: 'general' },
{ key: 'favicon_url', value: '', type: 'image_url', section: 'general' },
// Home
{ key: 'home_hero_title', value: 'GÜVENLİK SINIR <br /> <span class="text-transparent bg-clip-text bg-gradient-to-r from-slate-200 to-slate-500">TANIMAZ</span>', type: 'html', section: 'home' },
{ key: 'home_hero_description', value: 'En değerli varlıklarınız için tasarlanmış yüksek güvenlikli çelik kasalar. Modern teknoloji ve zanaatkarlığın mükemmel uyumu.', type: 'long_text', section: 'home' },
{ key: 'home_hero_button_text', value: 'Koleksiyonu İncele', type: 'text', section: 'home' },
{ key: 'home_hero_bg_image', value: '/images/hero-safe.png', type: 'image_url', section: 'home' },
{ key: 'home_categories_title', value: 'Ürün Kategorileri', type: 'text', section: 'home' },
{ key: 'home_categories_description', value: 'İhtiyacınıza uygun güvenlik çözümünü seçin.', type: 'text', section: 'home' },
// Contact
{ key: 'contact_phone', value: '', type: 'text', section: 'contact' },
@@ -37,6 +46,14 @@ export default async function SettingsPage() {
{ key: 'social_youtube', value: '', type: 'text', section: 'contact' },
{ key: 'social_tiktok', value: '', type: 'text', section: 'contact' },
{ key: 'contact_map_embed', value: '', type: 'html', section: 'contact' },
// SEO
{ key: 'meta_keywords', value: '', type: 'text', section: 'seo' },
{ key: 'meta_author', value: '', type: 'text', section: 'seo' },
// Scripts & Analytics
{ key: 'google_analytics_id', value: '', type: 'text', section: 'scripts' },
{ key: 'facebook_pixel_id', value: '', type: 'text', section: 'scripts' },
]
// Merge default contents with existing contents

View File

@@ -0,0 +1,65 @@
import { getSmsLogs } from "@/lib/sms/actions"
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table"
import { Badge } from "@/components/ui/badge"
import { format } from "date-fns"
import { tr } from "date-fns/locale"
export default async function SmsLogsPage() {
const { data: logs, error } = await getSmsLogs(100)
if (error) {
return <div className="p-8">Hata: {error}</div>
}
return (
<div className="flex-1 space-y-4 p-8 pt-6">
<h2 className="text-3xl font-bold tracking-tight">SMS Geçmişi</h2>
<p className="text-muted-foreground">Son gönderilen mesajların durumu.</p>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[180px]">Tarih</TableHead>
<TableHead>Numara</TableHead>
<TableHead>Mesaj</TableHead>
<TableHead>Durum</TableHead>
<TableHead className="text-right">Kod</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{logs?.length === 0 && (
<TableRow>
<TableCell colSpan={5} className="h-24 text-center">
Kayıt bulunamadı.
</TableCell>
</TableRow>
)}
{logs?.map((log) => (
<TableRow key={log.id}>
<TableCell className="font-medium">
{log.created_at ? format(new Date(log.created_at), "dd MMM yyyy HH:mm", { locale: tr }) : "-"}
</TableCell>
<TableCell>{log.phone}</TableCell>
<TableCell className="max-w-[300px] truncate" title={log.message}>{log.message}</TableCell>
<TableCell>
<Badge variant={log.status === 'success' ? 'default' : 'destructive'}>
{log.status === 'success' ? 'Başarılı' : 'Hatalı'}
</Badge>
</TableCell>
<TableCell className="text-right font-mono text-xs">{log.response_code}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
)
}

View File

@@ -0,0 +1,9 @@
import { getCustomers } from "@/lib/customers/actions"
import SmsPageClient from "@/components/dashboard/sms-page-client"
export default async function SmsPage() {
// Fetch all customers to show in the list
const { data: customers } = await getCustomers()
return <SmsPageClient customers={customers || []} />
}