Add order deletion functionality

- Add delete button to AdminOrders dialog with Trash2 and AlertTriangle icons
- Create delete-order edge function to handle deletion requests
- Add database migration for delete_order function with comprehensive cleanup
- Update config.toml to register delete-order edge function
- Deletion sequence: reviews → consulting slots → order items → user access → order

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
dwindown
2025-12-23 18:06:40 +07:00
parent e6b1e02e5f
commit 94403bd634
4 changed files with 191 additions and 1 deletions

View File

@@ -10,7 +10,7 @@ import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Skeleton } from "@/components/ui/skeleton";
import { formatIDR, formatDateTime } from "@/lib/format";
import { Eye, CheckCircle, XCircle, Video, ExternalLink } from "lucide-react";
import { Eye, CheckCircle, XCircle, Video, ExternalLink, Trash2, AlertTriangle } from "lucide-react";
import { toast } from "@/hooks/use-toast";
interface Order {
@@ -117,6 +117,35 @@ export default function AdminOrders() {
}
};
const deleteOrder = async (orderId: string) => {
// Confirm deletion
const confirmed = window.confirm(
"Apakah Anda yakin ingin menghapus order ini? Semua data terkait (review, slot konsultasi, akses produk) akan dihapus secara permanen."
);
if (!confirmed) return;
try {
const { data, error } = await supabase.functions.invoke("delete-order", {
body: { order_id: orderId },
});
if (error || !data?.success) {
throw new Error(data?.error || error?.message || "Gagal menghapus order");
}
toast({ title: "Berhasil", description: "Order dan semua data terkait berhasil dihapus" });
fetchOrders();
setDialogOpen(false);
} catch (error: any) {
toast({
title: "Error",
description: error.message || "Gagal menghapus order",
variant: "destructive",
});
}
};
const getStatusBadge = (status: string | null) => {
switch (status) {
case "paid":
@@ -290,6 +319,15 @@ export default function AdminOrders() {
Batalkan
</Button>
)}
<Button
variant="destructive"
onClick={() => deleteOrder(selectedOrder.id)}
className="gap-2"
>
<Trash2 className="w-4 h-4" />
<AlertTriangle className="w-4 h-4" />
Hapus Order
</Button>
</div>
</div>
)}