first commit
This commit is contained in:
178
app/(admin)/admin/cors/page.tsx
Normal file
178
app/(admin)/admin/cors/page.tsx
Normal file
@@ -0,0 +1,178 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { useAppDispatch, useAppSelector } from "@/lib/hooks";
|
||||
import {
|
||||
fetchWhitelists,
|
||||
fetchBlacklists,
|
||||
createWhitelist,
|
||||
createBlacklist,
|
||||
deleteWhitelist,
|
||||
deleteBlacklist,
|
||||
updateWhitelist,
|
||||
updateBlacklist,
|
||||
CorsEntry,
|
||||
} from "@/lib/features/cors/corsSlice";
|
||||
import { CorsTable } from "@/components/cors/cors-table";
|
||||
import { CorsDialog } from "@/components/cors/cors-dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Plus } from "lucide-react";
|
||||
import Swal from "sweetalert2";
|
||||
|
||||
export default function CorsPage() {
|
||||
const dispatch = useAppDispatch();
|
||||
const { whitelist, blacklist } = useAppSelector((state) => state.cors);
|
||||
const [activeTab, setActiveTab] = useState<"whitelist" | "blacklist">("whitelist");
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
// Dialog state
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [editingEntry, setEditingEntry] = useState<CorsEntry | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
dispatch(fetchWhitelists());
|
||||
dispatch(fetchBlacklists());
|
||||
}, [dispatch]);
|
||||
|
||||
if (!mounted) return null;
|
||||
|
||||
const handleDelete = (id: string) => {
|
||||
Swal.fire({
|
||||
title: 'Emin misiniz?',
|
||||
text: "Bu kaydı silmek istediğinize emin misiniz?",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: 'Evet, sil!',
|
||||
cancelButtonText: 'İptal'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
if (activeTab === "whitelist") {
|
||||
dispatch(deleteWhitelist(id)).then(() => {
|
||||
Swal.fire('Silindi!', 'Kayıt başarıyla silindi.', 'success');
|
||||
});
|
||||
} else {
|
||||
dispatch(deleteBlacklist(id)).then(() => {
|
||||
Swal.fire('Silindi!', 'Kayıt başarıyla silindi.', 'success');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleToggleActive = (id: string, currentStatus: boolean) => {
|
||||
const data = { is_active: !currentStatus };
|
||||
if (activeTab === "whitelist") {
|
||||
dispatch(updateWhitelist({ id, data }));
|
||||
} else {
|
||||
dispatch(updateBlacklist({ id, data }));
|
||||
}
|
||||
};
|
||||
|
||||
const handleEdit = (entry: CorsEntry) => {
|
||||
setEditingEntry(entry);
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleAddClick = () => {
|
||||
setEditingEntry(null);
|
||||
setDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleDialogSubmit = async (origin: string, note: string) => {
|
||||
if (editingEntry) {
|
||||
// Update existing
|
||||
const data: Partial<CorsEntry> = activeTab === "whitelist"
|
||||
? { origin, description: note }
|
||||
: { origin, reason: note };
|
||||
|
||||
if (activeTab === "whitelist") {
|
||||
await dispatch(updateWhitelist({ id: editingEntry.id, data })).unwrap();
|
||||
} else {
|
||||
await dispatch(updateBlacklist({ id: editingEntry.id, data })).unwrap();
|
||||
}
|
||||
Swal.fire('Güncellendi!', 'Kayıt başarıyla güncellendi.', 'success');
|
||||
} else {
|
||||
// Create new
|
||||
if (activeTab === "whitelist") {
|
||||
await dispatch(createWhitelist({ origin, description: note })).unwrap();
|
||||
} else {
|
||||
await dispatch(createBlacklist({ origin, reason: note })).unwrap();
|
||||
}
|
||||
Swal.fire('Eklendi!', 'Yeni kayıt başarıyla eklendi.', 'success');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-4">
|
||||
{/* Header / Breadcrumb Section */}
|
||||
<div className="flex items-center gap-2">
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem className="hidden md:block">
|
||||
<BreadcrumbLink href="/admin">Admin</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator className="hidden md:block" />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>CORS Ayarları</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
|
||||
<Separator />
|
||||
|
||||
{/* Actions & Dialog */}
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-x-2">
|
||||
<Button
|
||||
variant={activeTab === "whitelist" ? "default" : "outline"}
|
||||
onClick={() => setActiveTab("whitelist")}
|
||||
>
|
||||
Whitelist
|
||||
</Button>
|
||||
<Button
|
||||
variant={activeTab === "blacklist" ? "default" : "outline"}
|
||||
onClick={() => setActiveTab("blacklist")}
|
||||
>
|
||||
Blacklist
|
||||
</Button>
|
||||
</div>
|
||||
<Button onClick={handleAddClick}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Yeni Ekle
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<CorsDialog
|
||||
open={dialogOpen}
|
||||
onOpenChange={setDialogOpen}
|
||||
type={activeTab}
|
||||
entry={editingEntry}
|
||||
onSubmit={handleDialogSubmit}
|
||||
/>
|
||||
|
||||
{/* Table */}
|
||||
<div className="rounded-xl border bg-card">
|
||||
<CorsTable
|
||||
data={activeTab === "whitelist" ? whitelist : blacklist}
|
||||
type={activeTab}
|
||||
onDelete={handleDelete}
|
||||
onEdit={handleEdit}
|
||||
onToggleActive={handleToggleActive}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user