144 lines
5.7 KiB
TypeScript
144 lines
5.7 KiB
TypeScript
"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 { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
|
|
import {
|
|
AlertDialog,
|
|
AlertDialogAction,
|
|
AlertDialogCancel,
|
|
AlertDialogContent,
|
|
AlertDialogDescription,
|
|
AlertDialogFooter,
|
|
AlertDialogHeader,
|
|
AlertDialogTitle,
|
|
} from "@/components/ui/alert-dialog";
|
|
import { DataTable } from "@/components/data-table/data-table";
|
|
import { useBucketList, useCreateBucket, useDeleteBucket } from "@/modules/cms/bucket/hooks";
|
|
import { useToast } from "@/hooks/use-toast";
|
|
import { Plus, Trash } from "lucide-react";
|
|
import { ColumnDef } from "@tanstack/react-table";
|
|
import { Bucket } from "@/modules/cms/bucket/schemas";
|
|
|
|
export default function BucketsPage() {
|
|
const { toast } = useToast();
|
|
const { data, isLoading } = useBucketList();
|
|
const createMutation = useCreateBucket();
|
|
const deleteMutation = useDeleteBucket();
|
|
const [open, setOpen] = useState(false);
|
|
const [bucketName, setBucketName] = useState("");
|
|
const [deleteBucket, setDeleteBucket] = useState<{ name: string; id: string } | null>(null);
|
|
|
|
const handleCreate = async () => {
|
|
if (!bucketName) return;
|
|
|
|
try {
|
|
await createMutation.mutateAsync({ bucketName });
|
|
toast({ title: "Bucket created", description: "Bucket created successfully" });
|
|
setOpen(false);
|
|
setBucketName("");
|
|
} catch (error) {
|
|
toast({ title: "Create failed", variant: "destructive" });
|
|
}
|
|
};
|
|
|
|
const handleDelete = async () => {
|
|
if (!deleteBucket) return;
|
|
|
|
try {
|
|
await deleteMutation.mutateAsync(deleteBucket.name);
|
|
toast({ title: "Bucket deleted", description: "Bucket has been deleted successfully" });
|
|
setDeleteBucket(null);
|
|
} catch (error) {
|
|
toast({ title: "Delete failed", variant: "destructive" });
|
|
setDeleteBucket(null);
|
|
}
|
|
};
|
|
|
|
const columns: ColumnDef<Bucket>[] = [
|
|
{ accessorKey: "name", header: "Bucket Name" },
|
|
{ accessorKey: "policy", header: "Policy" },
|
|
{
|
|
id: "actions",
|
|
cell: ({ row }) => (
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
onClick={() => setDeleteBucket({ name: row.original.name, id: row.original.name })}
|
|
>
|
|
<Trash className="h-4 w-4 text-destructive" />
|
|
</Button>
|
|
),
|
|
},
|
|
];
|
|
|
|
const buckets = data?.data || [];
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h1 className="text-3xl font-bold">CMS Buckets</h1>
|
|
<p className="text-muted-foreground">Manage storage buckets</p>
|
|
</div>
|
|
<Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogTrigger asChild>
|
|
<Button>
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
Create Bucket
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle>Create Bucket</DialogTitle>
|
|
</DialogHeader>
|
|
<div className="space-y-4">
|
|
<div className="space-y-2">
|
|
<Label htmlFor="bucketName">Bucket Name</Label>
|
|
<Input
|
|
id="bucketName"
|
|
value={bucketName}
|
|
onChange={(e) => setBucketName(e.target.value)}
|
|
placeholder="my-bucket"
|
|
/>
|
|
</div>
|
|
<Button onClick={handleCreate} disabled={createMutation.isPending}>
|
|
{createMutation.isPending ? "Creating..." : "Create"}
|
|
</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
|
|
{isLoading ? (
|
|
<div>Loading...</div>
|
|
) : (
|
|
<DataTable columns={columns} data={buckets} searchKey="name" />
|
|
)}
|
|
|
|
<AlertDialog open={!!deleteBucket} onOpenChange={(open) => !open && setDeleteBucket(null)}>
|
|
<AlertDialogContent>
|
|
<AlertDialogHeader>
|
|
<AlertDialogTitle>Delete Bucket</AlertDialogTitle>
|
|
<AlertDialogDescription>
|
|
Are you sure you want to delete bucket "{deleteBucket?.name}"? This action cannot be undone and will remove all data in this bucket.
|
|
</AlertDialogDescription>
|
|
</AlertDialogHeader>
|
|
<AlertDialogFooter>
|
|
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
<AlertDialogAction
|
|
onClick={handleDelete}
|
|
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
|
|
>
|
|
Delete
|
|
</AlertDialogAction>
|
|
</AlertDialogFooter>
|
|
</AlertDialogContent>
|
|
</AlertDialog>
|
|
</div>
|
|
);
|
|
}
|