From 7390964d5691a15e2d1b62fe81127c8f7fec6e35 Mon Sep 17 00:00:00 2001 From: Taken Date: Thu, 26 Jun 2025 14:55:04 +0200 Subject: [PATCH] Updated list component --- src/components/dashboard/urls-data-table.tsx | 68 +++++++++++++------- src/lib/actions/url.ts | 29 +++++++++ 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/src/components/dashboard/urls-data-table.tsx b/src/components/dashboard/urls-data-table.tsx index 4feef35..829d3ed 100644 --- a/src/components/dashboard/urls-data-table.tsx +++ b/src/components/dashboard/urls-data-table.tsx @@ -12,7 +12,7 @@ import { useReactTable, VisibilityState } from "@tanstack/react-table" -import { ArrowUpDown, Check, Copy, ExternalLink, MoreHorizontal, Trash2, X } from "lucide-react" +import { ArrowUpDown, Check, Copy, MoreHorizontal, Trash2, X } from "lucide-react" import * as React from "react" import { Button } from "@/components/ui/button" @@ -27,19 +27,13 @@ import { } from "@/components/ui/dropdown-menu" import { Input } from "@/components/ui/input" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { deleteUrl } from "@/lib/actions/url" import { urls } from "@/lib/drizzle/schema" +import { useRouter } from "next/navigation" import { toast } from "sonner" type UrlRecord = typeof urls.$inferSelect -function handleCopy(string: string) { - navigator.clipboard.writeText(string).then(() => { - toast.success("URL copied to clipboard") - }).catch(() => { - toast.error("Failed to copy URL") - }) -} - export const columns: ColumnDef[] = [ { accessorKey: "slug", @@ -202,8 +196,39 @@ export const columns: ColumnDef[] = [ ) } - }, - { + } +] + +interface UrlsDataTableProps { + data: UrlRecord[] +} + +export function UrlsDataTable({ data }: UrlsDataTableProps) { + const [sorting, setSorting] = React.useState([]) + const [columnFilters, setColumnFilters] = React.useState([]) + const [columnVisibility, setColumnVisibility] = React.useState({}) + const router = useRouter() + + function handleCopy(string: string) { + navigator.clipboard.writeText(string).then(() => { + toast.success("URL copied to clipboard") + }).catch(() => { + toast.error("Failed to copy URL") + }) + } + + async function handleDelete(id: string) { + const res = await deleteUrl(id) + + if (res.error) { + toast.error("Failed to delete URL") + } else { + toast.success("URL deleted successfully") + router.refresh() + } + } + + const actionRow: ColumnDef = { id: "actions", enableHiding: false, cell: ({ row }) => { @@ -228,7 +253,12 @@ export const columns: ColumnDef[] = [ Copy URL - + { + handleDelete(urlRecord.id) + }} + > Delete @@ -237,20 +267,12 @@ export const columns: ColumnDef[] = [ ) } } -] -interface UrlsDataTableProps { - data: UrlRecord[] -} - -export function UrlsDataTable({ data }: UrlsDataTableProps) { - const [sorting, setSorting] = React.useState([]) - const [columnFilters, setColumnFilters] = React.useState([]) - const [columnVisibility, setColumnVisibility] = React.useState({}) + const tableColumns = React.useMemo(() => [...columns, actionRow], []) const table = useReactTable({ data, - columns, + columns: tableColumns, onSortingChange: setSorting, onColumnFiltersChange: setColumnFilters, getCoreRowModel: getCoreRowModel(), @@ -341,7 +363,7 @@ export function UrlsDataTable({ data }: UrlsDataTableProps) { ( No results. diff --git a/src/lib/actions/url.ts b/src/lib/actions/url.ts index 39e8f5b..ed74069 100644 --- a/src/lib/actions/url.ts +++ b/src/lib/actions/url.ts @@ -1,8 +1,10 @@ "use server" +import { z } from "zod" import { getSession } from "../auth/session" import { insertUrl } from "../db/urls" import { urlFormSchema } from "../schema/url" +import { deleteUrl as deleteUrlDb } from "../db/urls" type Response = { error: boolean @@ -34,4 +36,31 @@ export async function addUrl(unsafeData: unknown): Promise { error: false, message: "Short link created successfully!" } +} + +export async function deleteUrl(unsafe: unknown): Promise { + const { session } = await getSession() + + if (!session) { + return { + error: true, + message: "You must be logged in to create a short link." + } + } + + const { error, data: id } = z.string().safeParse(unsafe) + + if (error) { + return { + error: true, + message: "Error parsing form data." + } + } + + await deleteUrlDb(id) + + return { + error: false, + message: "Short link deleted successfully!" + } } \ No newline at end of file