From f68e17156f663b5adb0d6c3730daa277c15d36f3 Mon Sep 17 00:00:00 2001 From: TZGyn Date: Sun, 3 Sep 2023 01:51:16 +0800 Subject: [PATCH] New feature: category table --- app/api/bookmark_category/route.ts | 16 ++++-- app/categories/layout.tsx | 11 ++++ app/categories/page.tsx | 29 ++++++++++ app/categories/table.tsx | 83 +++++++++++++++++++++++++++++ components/icons.tsx | 85 ++++++++++++++++++++++++++++++ config/site.ts | 8 +++ 6 files changed, 229 insertions(+), 3 deletions(-) create mode 100644 app/categories/layout.tsx create mode 100644 app/categories/page.tsx create mode 100644 app/categories/table.tsx diff --git a/app/api/bookmark_category/route.ts b/app/api/bookmark_category/route.ts index 8adeb38..3920fd1 100644 --- a/app/api/bookmark_category/route.ts +++ b/app/api/bookmark_category/route.ts @@ -2,7 +2,7 @@ import { bookmarkCategorySchema, newBookmarkCategorySchema } from '@/types' import { NextRequest, NextResponse } from 'next/server' import { bookmarkCategory } from '@/lib/schema' import { db } from '@/lib/db' -import { eq } from 'drizzle-orm' +import { eq, and } from 'drizzle-orm' import { cookies } from 'next/headers' import { getUser } from '@/lib/auth' @@ -45,10 +45,20 @@ export const PATCH = async (request: NextRequest) => { export const DELETE = async (request: NextRequest) => { const body = await request.json() + const token = cookies().get('token') + + const session_user = await getUser(token) const bookmarkId = body.bookmarkCategoryId - await db.delete(bookmarkCategory).where(eq(bookmarkCategory.id, bookmarkId)) + await db + .delete(bookmarkCategory) + .where( + and( + eq(bookmarkCategory.id, bookmarkId), + eq(bookmarkCategory.userId, session_user ? session_user.id : 0) + ) + ) - return NextResponse.json({ message: 'Bookmark Deleted' }) + return NextResponse.json({ message: 'Bookmark Category Deleted' }) } diff --git a/app/categories/layout.tsx b/app/categories/layout.tsx new file mode 100644 index 0000000..4324312 --- /dev/null +++ b/app/categories/layout.tsx @@ -0,0 +1,11 @@ +export default function DashboardLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( +
+ {children} +
+ ) +} diff --git a/app/categories/page.tsx b/app/categories/page.tsx new file mode 100644 index 0000000..5528bea --- /dev/null +++ b/app/categories/page.tsx @@ -0,0 +1,29 @@ +import { + bookmarkCategorySchema, +} from '@/types' +import { db } from '@/lib/db' +import { cookies } from 'next/headers' +import { getUser } from '@/lib/auth' +import TableComponent from './table' + +export const dynamic = 'force-dynamic' +export const fetchCache = 'force-no-store' + +export default async function CategoriesPage() { + const token = cookies().get('token') + + const session_user = await getUser(token) + + const data = await db.query.bookmarkCategory.findMany({ + where: (bookmarkCategory, { eq }) => + eq(bookmarkCategory.userId, session_user ? session_user.id : 0), + }) + + const bookmarkCategories = bookmarkCategorySchema.array().parse(data) + + return ( +
+ +
+ ) +} diff --git a/app/categories/table.tsx b/app/categories/table.tsx new file mode 100644 index 0000000..6b268cb --- /dev/null +++ b/app/categories/table.tsx @@ -0,0 +1,83 @@ +'use client' + +import { + Table, + TableHeader, + TableColumn, + TableBody, + TableRow, + TableCell, + Tooltip, +} from '@nextui-org/react' +import { DeleteIcon, EditIcon } from '@/components/icons' +import { BookmarkCategory } from '@/types' + +import { useRouter } from 'next/navigation' + +const columns = [ + { name: 'NAME', uid: 'name' }, + { name: 'ACTIONS', uid: 'actions' }, +] + +export default function TableComponent({ + bookmarkCategories, +}: { + bookmarkCategories: BookmarkCategory[] +}) { + const router = useRouter() + + const deleteCategory = async (id: number) => { + if (!confirm('Do you want to delete this category?')) return + const body = { + bookmarkCategoryId: id, + } + await fetch('/api/bookmark_category', { + method: 'DELETE', + body: JSON.stringify(body), + }) + + router.refresh() + return + } + + return ( + <> + + + {(column) => ( + + {column.name} + + )} + + + {(item) => ( + + {item.name} + +
+ + + + + + + + deleteCategory(item.id) + }> + + + +
+
+
+ )} +
+
+ + ) +} diff --git a/components/icons.tsx b/components/icons.tsx index 3c8edad..bd0b82d 100644 --- a/components/icons.tsx +++ b/components/icons.tsx @@ -230,3 +230,88 @@ export const ChevronDown: React.FC = ({ ) } + +export const EditIcon: React.FC = (props) => ( + +) + +export const DeleteIcon: React.FC = (props) => ( + +) diff --git a/config/site.ts b/config/site.ts index 5f5c622..94a17bd 100644 --- a/config/site.ts +++ b/config/site.ts @@ -12,6 +12,10 @@ export const siteConfig = { label: 'Dashboard', href: '/dashboard', }, + { + label: 'Categories', + href: '/categories', + }, ], navMenuItems: [ { @@ -22,6 +26,10 @@ export const siteConfig = { label: 'Dashboard', href: '/dashboard', }, + { + label: 'Categories', + href: '/categories', + }, ], links: { github: 'https://github.com/TZGyn/',