Feat: Add Audit Logs page
This commit is contained in:
106
src/app/dashboard/settings/logs/page.tsx
Normal file
106
src/app/dashboard/settings/logs/page.tsx
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { createClient } from "@/lib/supabase/server"
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table"
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
|
import { Badge } from "@/components/ui/badge"
|
||||||
|
import { format } from "date-fns"
|
||||||
|
import { tr } from "date-fns/locale"
|
||||||
|
|
||||||
|
export default async function AuditLogsPage() {
|
||||||
|
const supabase = await createClient()
|
||||||
|
|
||||||
|
const { data: logs } = await supabase
|
||||||
|
.from('audit_logs')
|
||||||
|
.select(`
|
||||||
|
*,
|
||||||
|
profiles:user_id (full_name, role)
|
||||||
|
`)
|
||||||
|
.order('created_at', { ascending: false })
|
||||||
|
.limit(50)
|
||||||
|
|
||||||
|
const getActionBadge = (action: string) => {
|
||||||
|
if (action.includes('create')) return <Badge variant="default">Oluşturma</Badge>
|
||||||
|
if (action.includes('update')) return <Badge variant="secondary">Güncelleme</Badge>
|
||||||
|
if (action.includes('delete')) return <Badge variant="destructive">Silme</Badge>
|
||||||
|
if (action.includes('payment')) return <Badge className="bg-green-600">Ödeme</Badge>
|
||||||
|
return <Badge variant="outline">{action}</Badge>
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatActionText = (action: string, entityType: string) => {
|
||||||
|
switch (action) {
|
||||||
|
case 'create_reservation': return 'Yeni rezervasyon oluşturdu'
|
||||||
|
case 'update_reservation_status': return 'Rezervasyon durumunu güncelledi'
|
||||||
|
case 'add_payment': return 'Ödeme ekledi'
|
||||||
|
default: return `${entityType} üzerinde ${action} işlemi`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-6">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-3xl font-bold tracking-tight">İşlem Geçmişi</h2>
|
||||||
|
<p className="text-muted-foreground">Sistem üzerindeki son aktiviteler.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle>Son İşlemler</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<Table>
|
||||||
|
<TableHeader>
|
||||||
|
<TableRow>
|
||||||
|
<TableHead>Kullanıcı</TableHead>
|
||||||
|
<TableHead>İşlem</TableHead>
|
||||||
|
<TableHead>Detay</TableHead>
|
||||||
|
<TableHead>Tarih</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{logs?.length === 0 ? (
|
||||||
|
<TableRow>
|
||||||
|
<TableCell colSpan={4} className="text-center h-24 text-muted-foreground">
|
||||||
|
Kayıt bulunamadı.
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
) : (
|
||||||
|
logs?.map((log) => (
|
||||||
|
<TableRow key={log.id}>
|
||||||
|
<TableCell className="font-medium">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="h-6 w-6 rounded-full bg-primary/10 flex items-center justify-center text-primary font-bold text-xs">
|
||||||
|
{log.profiles?.full_name?.substring(0, 2).toUpperCase() || 'US'}
|
||||||
|
</div>
|
||||||
|
{log.profiles?.full_name || 'Bilinmeyen Kullanıcı'}
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
{getActionBadge(log.action)}
|
||||||
|
<span className="text-sm text-muted-foreground">
|
||||||
|
{formatActionText(log.action, log.entity_type)}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="max-w-xs truncate text-muted-foreground text-xs font-mono">
|
||||||
|
{JSON.stringify(log.details)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="text-muted-foreground text-sm">
|
||||||
|
{format(new Date(log.created_at), 'd MMM yyyy HH:mm', { locale: tr })}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Utensils, Users } from "lucide-react"
|
import { Utensils, Users, Activity } from "lucide-react"
|
||||||
|
|
||||||
export default function SettingsPage() {
|
export default function SettingsPage() {
|
||||||
return (
|
return (
|
||||||
@@ -33,6 +33,19 @@ export default function SettingsPage() {
|
|||||||
</CardHeader>
|
</CardHeader>
|
||||||
</Card>
|
</Card>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
<Link href="/dashboard/settings/logs">
|
||||||
|
<Card className="hover:bg-muted/50 transition-colors cursor-pointer">
|
||||||
|
<CardHeader>
|
||||||
|
<CardTitle className="flex items-center gap-2">
|
||||||
|
<Activity className="h-5 w-5" /> İşlem Geçmişi
|
||||||
|
</CardTitle>
|
||||||
|
<CardDescription>
|
||||||
|
Sistem üzerindeki tüm aktiviteleri görüntüleyin.
|
||||||
|
</CardDescription>
|
||||||
|
</CardHeader>
|
||||||
|
</Card>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user