feat: can manage tags

This commit is contained in:
0xzio
2025-02-11 00:05:14 +08:00
parent ca037a613d
commit 1df460d8dd
5 changed files with 114 additions and 0 deletions

View File

@@ -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>

View 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>
</>
)
}

View 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>
)
}

View File

@@ -0,0 +1,5 @@
import { TagList } from './TagList'
export default function Page() {
return <TagList />
}

View File

@@ -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 }) => {