Updated list component
This commit is contained in:
@@ -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<UrlRecord>[] = [
|
||||
{
|
||||
accessorKey: "slug",
|
||||
@@ -202,8 +196,39 @@ export const columns: ColumnDef<UrlRecord>[] = [
|
||||
</div>
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
}
|
||||
]
|
||||
|
||||
interface UrlsDataTableProps {
|
||||
data: UrlRecord[]
|
||||
}
|
||||
|
||||
export function UrlsDataTable({ data }: UrlsDataTableProps) {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
|
||||
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<UrlRecord> = {
|
||||
id: "actions",
|
||||
enableHiding: false,
|
||||
cell: ({ row }) => {
|
||||
@@ -228,7 +253,12 @@ export const columns: ColumnDef<UrlRecord>[] = [
|
||||
Copy URL
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem className="text-red-600">
|
||||
<DropdownMenuItem
|
||||
className="text-red-600"
|
||||
onClick={() => {
|
||||
handleDelete(urlRecord.id)
|
||||
}}
|
||||
>
|
||||
<Trash2 className="mr-2 h-4 w-4" />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
@@ -237,20 +267,12 @@ export const columns: ColumnDef<UrlRecord>[] = [
|
||||
)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
interface UrlsDataTableProps {
|
||||
data: UrlRecord[]
|
||||
}
|
||||
|
||||
export function UrlsDataTable({ data }: UrlsDataTableProps) {
|
||||
const [sorting, setSorting] = React.useState<SortingState>([])
|
||||
const [columnFilters, setColumnFilters] = React.useState<ColumnFiltersState>([])
|
||||
const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({})
|
||||
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) {
|
||||
(
|
||||
<TableRow>
|
||||
<TableCell
|
||||
colSpan={columns.length}
|
||||
colSpan={tableColumns.length}
|
||||
className="h-24 text-center"
|
||||
>
|
||||
No results.
|
||||
|
||||
@@ -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<Response> {
|
||||
error: false,
|
||||
message: "Short link created successfully!"
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteUrl(unsafe: unknown): Promise<Response> {
|
||||
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!"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user