New feature: category table
parent
4f0cfae03b
commit
f68e17156f
@ -0,0 +1,11 @@
|
||||
export default function DashboardLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
return (
|
||||
<section className='flex flex-col items-center justify-center gap-4 pt-10 sm:pt-16'>
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@ -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 (
|
||||
<div className='flex w-full max-w-4xl flex-row flex-wrap justify-start gap-6'>
|
||||
<TableComponent bookmarkCategories={bookmarkCategories} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -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 (
|
||||
<>
|
||||
<Table>
|
||||
<TableHeader columns={columns}>
|
||||
{(column) => (
|
||||
<TableColumn key={column.uid}>
|
||||
{column.name}
|
||||
</TableColumn>
|
||||
)}
|
||||
</TableHeader>
|
||||
<TableBody items={bookmarkCategories}>
|
||||
{(item) => (
|
||||
<TableRow key={item.id}>
|
||||
<TableCell>{item.name}</TableCell>
|
||||
<TableCell>
|
||||
<div className='relative flex items-center gap-2'>
|
||||
<Tooltip content='Edit user'>
|
||||
<span className='cursor-pointer text-lg text-default-400 active:opacity-50'>
|
||||
<EditIcon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
color='danger'
|
||||
content='Delete user'>
|
||||
<span
|
||||
className='cursor-pointer text-lg text-danger active:opacity-50'
|
||||
onClick={() =>
|
||||
deleteCategory(item.id)
|
||||
}>
|
||||
<DeleteIcon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</>
|
||||
)
|
||||
}
|
||||
Loading…
Reference in New Issue