mirror of
https://github.com/penxio/penx.git
synced 2026-04-19 03:03:06 -04:00
feat: can manage tags
This commit is contained in:
@@ -15,6 +15,7 @@ export function SettingNav({}: Props) {
|
||||
linkAccounts: '/~/settings/link-accounts',
|
||||
appearance: '/~/settings/appearance',
|
||||
socials: '/~/settings/socials',
|
||||
tags: '/~/settings/tags',
|
||||
web3: '/~/settings/web3',
|
||||
contributors: '/~/settings/contributors',
|
||||
}
|
||||
@@ -47,6 +48,10 @@ export function SettingNav({}: Props) {
|
||||
<Link href={Paths.web3} className={linkClassName(Paths.web3)}>
|
||||
Web3
|
||||
</Link>
|
||||
<Link href={Paths.tags} className={linkClassName(Paths.tags)}>
|
||||
Tags
|
||||
</Link>
|
||||
|
||||
<Link href={Paths.socials} className={linkClassName(Paths.socials)}>
|
||||
Socials
|
||||
</Link>
|
||||
|
||||
74
app/~/(dashboard)/settings/tags/TagList.tsx
Normal file
74
app/~/(dashboard)/settings/tags/TagList.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
'use client'
|
||||
|
||||
import { format } from 'date-fns'
|
||||
import { toast } from 'sonner'
|
||||
import { DeleteConfirmDialog } from '@/components/DeleteConfirmDialog'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from '@/components/ui/table'
|
||||
import { useQuerySite } from '@/lib/hooks/useQuerySite'
|
||||
import { useSiteTags } from '@/lib/hooks/useSiteTags'
|
||||
import { Site } from '@/lib/theme.types'
|
||||
import { api } from '@/lib/trpc'
|
||||
|
||||
interface Props {
|
||||
site: Site
|
||||
}
|
||||
|
||||
export function TagList({ site }: Props) {
|
||||
const { data = [], isLoading, refetch } = useSiteTags()
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="grid gap-4 mt-2">
|
||||
{Array(5)
|
||||
.fill('')
|
||||
.map((_, i) => (
|
||||
<Skeleton key={i} className="h-[60px] rounded-lg" />
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Name</TableHead>
|
||||
<TableHead>Created date</TableHead>
|
||||
<TableHead>Operation</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{data.map((item, index) => (
|
||||
<TableRow key={index}>
|
||||
<TableCell>{item.name}</TableCell>
|
||||
<TableCell>{format(item.createdAt, 'yyyy/MM/dd')}</TableCell>
|
||||
<TableCell>
|
||||
<DeleteConfirmDialog
|
||||
title={`Delete tag: ${item.name}`}
|
||||
content="All tags in post will be deleted, are you sure you want to delete this tag?"
|
||||
tooltipContent="Delete tag"
|
||||
onConfirm={async () => {
|
||||
await api.tag.deleteTag.mutate({
|
||||
tagId: item.id,
|
||||
})
|
||||
await refetch()
|
||||
toast.success('Tag deleted successfully!')
|
||||
}}
|
||||
/>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</>
|
||||
)
|
||||
}
|
||||
12
app/~/(dashboard)/settings/tags/layout.tsx
Normal file
12
app/~/(dashboard)/settings/tags/layout.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
export default function Layout({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-col justify-between">
|
||||
<div className="text-3xl font-bold">Manage tags</div>
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
5
app/~/(dashboard)/settings/tags/page.tsx
Normal file
5
app/~/(dashboard)/settings/tags/page.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
import { TagList } from './TagList'
|
||||
|
||||
export default function Page() {
|
||||
return <TagList />
|
||||
}
|
||||
@@ -99,6 +99,24 @@ export const tagRouter = router({
|
||||
return res!
|
||||
}),
|
||||
|
||||
deleteTag: protectedProcedure
|
||||
.input(
|
||||
z.object({
|
||||
tagId: z.string(),
|
||||
}),
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
// const tag = await db.query.tags.findFirst({
|
||||
// where: eq(tags.id, input.tagId),
|
||||
// })
|
||||
|
||||
await db.delete(postTags).where(eq(postTags.id, input.tagId))
|
||||
await db.delete(tags).where(eq(tags.id, input.tagId))
|
||||
|
||||
revalidate()
|
||||
return true
|
||||
}),
|
||||
|
||||
deletePostTag: protectedProcedure
|
||||
.input(z.string())
|
||||
.mutation(async ({ input }) => {
|
||||
|
||||
Reference in New Issue
Block a user