feat(app): refactor changelog routing, add changelog update route
This commit is contained in:
parent
23471aa9b0
commit
e45d498f56
@ -1,6 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
ChangelogCreateInput,
|
ChangelogCreateInput,
|
||||||
ChangelogOutput,
|
ChangelogOutput,
|
||||||
|
ChangelogUpdateInput,
|
||||||
} from '@boring.tools/schema'
|
} from '@boring.tools/schema'
|
||||||
import { useAuth } from '@clerk/clerk-react'
|
import { useAuth } from '@clerk/clerk-react'
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||||
@ -9,6 +10,7 @@ import { queryFetch } from '../utils/queryFetch'
|
|||||||
|
|
||||||
type Changelog = z.infer<typeof ChangelogOutput>
|
type Changelog = z.infer<typeof ChangelogOutput>
|
||||||
type ChangelogCreate = z.infer<typeof ChangelogCreateInput>
|
type ChangelogCreate = z.infer<typeof ChangelogCreateInput>
|
||||||
|
type ChangelogUpdate = z.infer<typeof ChangelogUpdateInput>
|
||||||
|
|
||||||
export const useChangelogList = () => {
|
export const useChangelogList = () => {
|
||||||
const { getToken } = useAuth()
|
const { getToken } = useAuth()
|
||||||
@ -57,6 +59,32 @@ export const useChangelogCreate = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useChangelogUpdate = () => {
|
||||||
|
const { getToken } = useAuth()
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async ({
|
||||||
|
id,
|
||||||
|
payload,
|
||||||
|
}: {
|
||||||
|
id: string
|
||||||
|
payload: ChangelogUpdate
|
||||||
|
}): Promise<Readonly<Changelog>> =>
|
||||||
|
await queryFetch({
|
||||||
|
path: `changelog/${id}`,
|
||||||
|
data: payload,
|
||||||
|
method: 'put',
|
||||||
|
token: await getToken(),
|
||||||
|
}),
|
||||||
|
onSuccess: (data) => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: ['changelogById', data.id],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const useChangelogRemove = () => {
|
export const useChangelogRemove = () => {
|
||||||
const { getToken } = useAuth()
|
const { getToken } = useAuth()
|
||||||
const queryClient = useQueryClient()
|
const queryClient = useQueryClient()
|
||||||
|
@ -21,6 +21,7 @@ const UserIndexLazyImport = createFileRoute('/user/')()
|
|||||||
const ChangelogIndexLazyImport = createFileRoute('/changelog/')()
|
const ChangelogIndexLazyImport = createFileRoute('/changelog/')()
|
||||||
const ChangelogCreateLazyImport = createFileRoute('/changelog/create')()
|
const ChangelogCreateLazyImport = createFileRoute('/changelog/create')()
|
||||||
const ChangelogIdLazyImport = createFileRoute('/changelog/$id')()
|
const ChangelogIdLazyImport = createFileRoute('/changelog/$id')()
|
||||||
|
const ChangelogIdEditLazyImport = createFileRoute('/changelog/$id/edit')()
|
||||||
|
|
||||||
// Create/Update Routes
|
// Create/Update Routes
|
||||||
|
|
||||||
@ -38,20 +39,27 @@ const ChangelogIndexLazyRoute = ChangelogIndexLazyImport.update({
|
|||||||
path: '/changelog/',
|
path: '/changelog/',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() =>
|
} as any).lazy(() =>
|
||||||
import('./routes/changelog/index.lazy').then((d) => d.Route),
|
import('./routes/changelog.index.lazy').then((d) => d.Route),
|
||||||
)
|
)
|
||||||
|
|
||||||
const ChangelogCreateLazyRoute = ChangelogCreateLazyImport.update({
|
const ChangelogCreateLazyRoute = ChangelogCreateLazyImport.update({
|
||||||
path: '/changelog/create',
|
path: '/changelog/create',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() =>
|
} as any).lazy(() =>
|
||||||
import('./routes/changelog/create.lazy').then((d) => d.Route),
|
import('./routes/changelog.create.lazy').then((d) => d.Route),
|
||||||
)
|
)
|
||||||
|
|
||||||
const ChangelogIdLazyRoute = ChangelogIdLazyImport.update({
|
const ChangelogIdLazyRoute = ChangelogIdLazyImport.update({
|
||||||
path: '/changelog/$id',
|
path: '/changelog/$id',
|
||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() => import('./routes/changelog/$id.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/changelog.$id.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
|
const ChangelogIdEditLazyRoute = ChangelogIdEditLazyImport.update({
|
||||||
|
path: '/edit',
|
||||||
|
getParentRoute: () => ChangelogIdLazyRoute,
|
||||||
|
} as any).lazy(() =>
|
||||||
|
import('./routes/changelog.$id.edit.lazy').then((d) => d.Route),
|
||||||
|
)
|
||||||
|
|
||||||
// Populate the FileRoutesByPath interface
|
// Populate the FileRoutesByPath interface
|
||||||
|
|
||||||
@ -92,34 +100,56 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof UserIndexLazyImport
|
preLoaderRoute: typeof UserIndexLazyImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/changelog/$id/edit': {
|
||||||
|
id: '/changelog/$id/edit'
|
||||||
|
path: '/edit'
|
||||||
|
fullPath: '/changelog/$id/edit'
|
||||||
|
preLoaderRoute: typeof ChangelogIdEditLazyImport
|
||||||
|
parentRoute: typeof ChangelogIdLazyImport
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and export the route tree
|
// Create and export the route tree
|
||||||
|
|
||||||
|
interface ChangelogIdLazyRouteChildren {
|
||||||
|
ChangelogIdEditLazyRoute: typeof ChangelogIdEditLazyRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChangelogIdLazyRouteChildren: ChangelogIdLazyRouteChildren = {
|
||||||
|
ChangelogIdEditLazyRoute: ChangelogIdEditLazyRoute,
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChangelogIdLazyRouteWithChildren = ChangelogIdLazyRoute._addFileChildren(
|
||||||
|
ChangelogIdLazyRouteChildren,
|
||||||
|
)
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexLazyRoute
|
'/': typeof IndexLazyRoute
|
||||||
'/changelog/$id': typeof ChangelogIdLazyRoute
|
'/changelog/$id': typeof ChangelogIdLazyRouteWithChildren
|
||||||
'/changelog/create': typeof ChangelogCreateLazyRoute
|
'/changelog/create': typeof ChangelogCreateLazyRoute
|
||||||
'/changelog': typeof ChangelogIndexLazyRoute
|
'/changelog': typeof ChangelogIndexLazyRoute
|
||||||
'/user': typeof UserIndexLazyRoute
|
'/user': typeof UserIndexLazyRoute
|
||||||
|
'/changelog/$id/edit': typeof ChangelogIdEditLazyRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexLazyRoute
|
'/': typeof IndexLazyRoute
|
||||||
'/changelog/$id': typeof ChangelogIdLazyRoute
|
'/changelog/$id': typeof ChangelogIdLazyRouteWithChildren
|
||||||
'/changelog/create': typeof ChangelogCreateLazyRoute
|
'/changelog/create': typeof ChangelogCreateLazyRoute
|
||||||
'/changelog': typeof ChangelogIndexLazyRoute
|
'/changelog': typeof ChangelogIndexLazyRoute
|
||||||
'/user': typeof UserIndexLazyRoute
|
'/user': typeof UserIndexLazyRoute
|
||||||
|
'/changelog/$id/edit': typeof ChangelogIdEditLazyRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
__root__: typeof rootRoute
|
__root__: typeof rootRoute
|
||||||
'/': typeof IndexLazyRoute
|
'/': typeof IndexLazyRoute
|
||||||
'/changelog/$id': typeof ChangelogIdLazyRoute
|
'/changelog/$id': typeof ChangelogIdLazyRouteWithChildren
|
||||||
'/changelog/create': typeof ChangelogCreateLazyRoute
|
'/changelog/create': typeof ChangelogCreateLazyRoute
|
||||||
'/changelog/': typeof ChangelogIndexLazyRoute
|
'/changelog/': typeof ChangelogIndexLazyRoute
|
||||||
'/user/': typeof UserIndexLazyRoute
|
'/user/': typeof UserIndexLazyRoute
|
||||||
|
'/changelog/$id/edit': typeof ChangelogIdEditLazyRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FileRouteTypes {
|
export interface FileRouteTypes {
|
||||||
@ -130,8 +160,15 @@ export interface FileRouteTypes {
|
|||||||
| '/changelog/create'
|
| '/changelog/create'
|
||||||
| '/changelog'
|
| '/changelog'
|
||||||
| '/user'
|
| '/user'
|
||||||
|
| '/changelog/$id/edit'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to: '/' | '/changelog/$id' | '/changelog/create' | '/changelog' | '/user'
|
to:
|
||||||
|
| '/'
|
||||||
|
| '/changelog/$id'
|
||||||
|
| '/changelog/create'
|
||||||
|
| '/changelog'
|
||||||
|
| '/user'
|
||||||
|
| '/changelog/$id/edit'
|
||||||
id:
|
id:
|
||||||
| '__root__'
|
| '__root__'
|
||||||
| '/'
|
| '/'
|
||||||
@ -139,12 +176,13 @@ export interface FileRouteTypes {
|
|||||||
| '/changelog/create'
|
| '/changelog/create'
|
||||||
| '/changelog/'
|
| '/changelog/'
|
||||||
| '/user/'
|
| '/user/'
|
||||||
|
| '/changelog/$id/edit'
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexLazyRoute: typeof IndexLazyRoute
|
IndexLazyRoute: typeof IndexLazyRoute
|
||||||
ChangelogIdLazyRoute: typeof ChangelogIdLazyRoute
|
ChangelogIdLazyRoute: typeof ChangelogIdLazyRouteWithChildren
|
||||||
ChangelogCreateLazyRoute: typeof ChangelogCreateLazyRoute
|
ChangelogCreateLazyRoute: typeof ChangelogCreateLazyRoute
|
||||||
ChangelogIndexLazyRoute: typeof ChangelogIndexLazyRoute
|
ChangelogIndexLazyRoute: typeof ChangelogIndexLazyRoute
|
||||||
UserIndexLazyRoute: typeof UserIndexLazyRoute
|
UserIndexLazyRoute: typeof UserIndexLazyRoute
|
||||||
@ -152,7 +190,7 @@ export interface RootRouteChildren {
|
|||||||
|
|
||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
IndexLazyRoute: IndexLazyRoute,
|
IndexLazyRoute: IndexLazyRoute,
|
||||||
ChangelogIdLazyRoute: ChangelogIdLazyRoute,
|
ChangelogIdLazyRoute: ChangelogIdLazyRouteWithChildren,
|
||||||
ChangelogCreateLazyRoute: ChangelogCreateLazyRoute,
|
ChangelogCreateLazyRoute: ChangelogCreateLazyRoute,
|
||||||
ChangelogIndexLazyRoute: ChangelogIndexLazyRoute,
|
ChangelogIndexLazyRoute: ChangelogIndexLazyRoute,
|
||||||
UserIndexLazyRoute: UserIndexLazyRoute,
|
UserIndexLazyRoute: UserIndexLazyRoute,
|
||||||
@ -181,16 +219,23 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "index.lazy.tsx"
|
"filePath": "index.lazy.tsx"
|
||||||
},
|
},
|
||||||
"/changelog/$id": {
|
"/changelog/$id": {
|
||||||
"filePath": "changelog/$id.lazy.tsx"
|
"filePath": "changelog.$id.lazy.tsx",
|
||||||
|
"children": [
|
||||||
|
"/changelog/$id/edit"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"/changelog/create": {
|
"/changelog/create": {
|
||||||
"filePath": "changelog/create.lazy.tsx"
|
"filePath": "changelog.create.lazy.tsx"
|
||||||
},
|
},
|
||||||
"/changelog/": {
|
"/changelog/": {
|
||||||
"filePath": "changelog/index.lazy.tsx"
|
"filePath": "changelog.index.lazy.tsx"
|
||||||
},
|
},
|
||||||
"/user/": {
|
"/user/": {
|
||||||
"filePath": "user/index.lazy.tsx"
|
"filePath": "user/index.lazy.tsx"
|
||||||
|
},
|
||||||
|
"/changelog/$id/edit": {
|
||||||
|
"filePath": "changelog.$id.edit.lazy.tsx",
|
||||||
|
"parent": "/changelog/$id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
142
apps/app/src/routes/changelog.$id.edit.lazy.tsx
Normal file
142
apps/app/src/routes/changelog.$id.edit.lazy.tsx
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Checkbox,
|
||||||
|
Form,
|
||||||
|
FormControl,
|
||||||
|
FormDescription,
|
||||||
|
FormField,
|
||||||
|
FormItem,
|
||||||
|
FormLabel,
|
||||||
|
FormMessage,
|
||||||
|
Input,
|
||||||
|
Textarea,
|
||||||
|
} from '@boring.tools/ui'
|
||||||
|
import { createLazyFileRoute, useNavigate } from '@tanstack/react-router'
|
||||||
|
|
||||||
|
import { ChangelogUpdateInput } from '@boring.tools/schema'
|
||||||
|
import { zodResolver } from '@hookform/resolvers/zod'
|
||||||
|
import { useForm } from 'react-hook-form'
|
||||||
|
import type { z } from 'zod'
|
||||||
|
import { useChangelogById, useChangelogUpdate } from '../hooks/useChangelog'
|
||||||
|
|
||||||
|
const Component = () => {
|
||||||
|
const { id } = Route.useParams()
|
||||||
|
const { data, error, isPending, refetch } = useChangelogById({ id })
|
||||||
|
const navigate = useNavigate({ from: '/changelog/$id/edit' })
|
||||||
|
const changelogCreate = useChangelogUpdate()
|
||||||
|
const form = useForm<z.infer<typeof ChangelogUpdateInput>>({
|
||||||
|
resolver: zodResolver(ChangelogUpdateInput),
|
||||||
|
defaultValues: data,
|
||||||
|
})
|
||||||
|
|
||||||
|
const onSubmit = (payload: z.infer<typeof ChangelogUpdateInput>) => {
|
||||||
|
changelogCreate.mutate(
|
||||||
|
{ id, payload },
|
||||||
|
{
|
||||||
|
onSuccess(data) {
|
||||||
|
navigate({ to: '/changelog/$id', params: { id: data.id } })
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="flex items-center justify-center mt-32 flex-col">
|
||||||
|
<h1 className="text-3xl">Changelogs</h1>
|
||||||
|
<p>Please try again later</p>
|
||||||
|
|
||||||
|
<Button onClick={() => refetch()}>Retry</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col gap-5">
|
||||||
|
{!isPending && data && (
|
||||||
|
<div>
|
||||||
|
<Form {...form}>
|
||||||
|
<form
|
||||||
|
onSubmit={form.handleSubmit(onSubmit)}
|
||||||
|
className="space-y-8 max-w-screen-md"
|
||||||
|
>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="title"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Title</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Input placeholder="My changelog" {...field} autoFocus />
|
||||||
|
</FormControl>{' '}
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="description"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>Description</FormLabel>
|
||||||
|
<FormControl>
|
||||||
|
<Textarea
|
||||||
|
placeholder="Some details about the changelog..."
|
||||||
|
{...field}
|
||||||
|
/>
|
||||||
|
</FormControl>{' '}
|
||||||
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="isSemver"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="flex flex-row items-start space-x-3 space-y-0 rounded-md ">
|
||||||
|
<FormControl>
|
||||||
|
<Checkbox
|
||||||
|
checked={field.value}
|
||||||
|
onCheckedChange={field.onChange}
|
||||||
|
/>
|
||||||
|
</FormControl>
|
||||||
|
<div className="space-y-1 leading-none">
|
||||||
|
<FormLabel>Using Semver</FormLabel>
|
||||||
|
<FormDescription>
|
||||||
|
If this changelog is following the{' '}
|
||||||
|
<a
|
||||||
|
href="https://semver.org/lang/de/"
|
||||||
|
className="text-emerald-700"
|
||||||
|
>
|
||||||
|
semantic versioning?
|
||||||
|
</a>
|
||||||
|
</FormDescription>
|
||||||
|
</div>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<div className="flex gap-5">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant={'ghost'}
|
||||||
|
onClick={() =>
|
||||||
|
navigate({ to: '/changelog/$id', params: { id } })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button type="submit">Update</Button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Route = createLazyFileRoute('/changelog/$id/edit')({
|
||||||
|
component: Component,
|
||||||
|
})
|
@ -4,16 +4,15 @@ import {
|
|||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '@boring.tools/ui'
|
} from '@boring.tools/ui'
|
||||||
import { createLazyFileRoute } from '@tanstack/react-router'
|
import { Link, Outlet, createLazyFileRoute } from '@tanstack/react-router'
|
||||||
import {
|
import {
|
||||||
FileStackIcon,
|
FileStackIcon,
|
||||||
Globe2Icon,
|
Globe2Icon,
|
||||||
PencilIcon,
|
PencilIcon,
|
||||||
TerminalSquareIcon,
|
TerminalSquareIcon,
|
||||||
Trash2Icon,
|
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { ChangelogDelete } from '../../components/Changelog/Delete'
|
import { ChangelogDelete } from '../components/Changelog/Delete'
|
||||||
import { useChangelogById } from '../../hooks/useChangelog'
|
import { useChangelogById } from '../hooks/useChangelog'
|
||||||
|
|
||||||
const Component = () => {
|
const Component = () => {
|
||||||
const { id } = Route.useParams()
|
const { id } = Route.useParams()
|
||||||
@ -72,9 +71,11 @@ const Component = () => {
|
|||||||
|
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button variant={'ghost'}>
|
<Link to={'/changelog/$id/edit'} params={{ id }}>
|
||||||
<PencilIcon strokeWidth={1.5} />
|
<Button variant={'ghost'}>
|
||||||
</Button>
|
<PencilIcon strokeWidth={1.5} />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p>Edit</p>
|
<p>Edit</p>
|
||||||
@ -84,6 +85,8 @@ const Component = () => {
|
|||||||
<ChangelogDelete id={id} />
|
<ChangelogDelete id={id} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
@ -17,7 +17,7 @@ import { createLazyFileRoute } from '@tanstack/react-router'
|
|||||||
import { useNavigate } from '@tanstack/react-router'
|
import { useNavigate } from '@tanstack/react-router'
|
||||||
import { useForm } from 'react-hook-form'
|
import { useForm } from 'react-hook-form'
|
||||||
import type { z } from 'zod'
|
import type { z } from 'zod'
|
||||||
import { useChangelogCreate } from '../../hooks/useChangelog'
|
import { useChangelogCreate } from '../hooks/useChangelog'
|
||||||
|
|
||||||
const Component = () => {
|
const Component = () => {
|
||||||
const navigate = useNavigate({ from: '/changelog/create' })
|
const navigate = useNavigate({ from: '/changelog/create' })
|
@ -7,7 +7,7 @@ import {
|
|||||||
} from '@boring.tools/ui'
|
} from '@boring.tools/ui'
|
||||||
import { Link, createLazyFileRoute } from '@tanstack/react-router'
|
import { Link, createLazyFileRoute } from '@tanstack/react-router'
|
||||||
import { PlusCircleIcon } from 'lucide-react'
|
import { PlusCircleIcon } from 'lucide-react'
|
||||||
import { useChangelogList } from '../../hooks/useChangelog'
|
import { useChangelogList } from '../hooks/useChangelog'
|
||||||
|
|
||||||
const Component = () => {
|
const Component = () => {
|
||||||
const { data, error, isPending, refetch } = useChangelogList()
|
const { data, error, isPending, refetch } = useChangelogList()
|
Loading…
Reference in New Issue
Block a user