1
- import { getPage , getPages } from "@/app/source"
2
- import { DocsPage , DocsBody } from "fumadocs-ui/page"
1
+ import { openapi , utils } from "@/app/source"
2
+ import { DocsPage , DocsBody , DocsTitle , DocsDescription } from "fumadocs-ui/page"
3
3
import { notFound } from "next/navigation"
4
- import { RollButton } from "fumadocs-ui/components/roll-button"
5
- import type { Metadata } from "next"
6
- import { join } from "path"
7
- import { getGithubLastEdit } from "fumadocs-core/server"
4
+ import defaultComponents from "fumadocs-ui/mdx"
5
+ import { Popup , PopupContent , PopupTrigger } from "fumadocs-ui/twoslash/popup"
6
+ import { Tab , Tabs } from "fumadocs-ui/components/tabs"
7
+ import { Callout } from "fumadocs-ui/components/callout"
8
+ import { TypeTable } from "fumadocs-ui/components/type-table"
9
+ import { Accordion , Accordions } from "fumadocs-ui/components/accordion"
10
+ import ImageSection from "@/app/components/ImageSection"
11
+ import type { ComponentProps , FC } from "react"
8
12
9
- export default async function Page ( { params } : { params : { slug ?: string [ ] } } ) {
10
- const page = getPage ( params . slug )
13
+ interface Param {
14
+ slug : string [ ]
15
+ }
16
+
17
+ export default function Page ( { params } : { params : Param } ) : React . ReactElement {
18
+ const page = utils . getPage ( params . slug )
11
19
12
20
if ( ! page ) notFound ( )
13
21
@@ -17,7 +25,7 @@ export default async function Page({ params }: { params: { slug?: string[] } })
17
25
href = { `https://github.com/gitbutlerapp/gitbutler-docs/blob/main/content/docs/${ page . file . path } ` }
18
26
target = "_blank"
19
27
rel = "noreferrer noopener"
20
- className = "group rounded-md text-neutral-500 dark:text-neutral-400 dark:bg-neutral-900 border border-neutral-300/50 text-sm py-1 dark:border- neutral-700 flex justify-center items-center gap-2 hover :bg-neutral-100 transition duration-300 dark:hover:bg-neutral-950"
28
+ className = "group flex items-center justify-center gap-2 rounded-md border border-neutral-300/50 py-1 text-sm text- neutral-500 transition duration-300 hover:bg-neutral-100 dark:border-neutral-700 dark :bg-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-950"
21
29
>
22
30
< svg
23
31
className = "size-4 group-hover:animate-[var(--animation-shake-x)]"
@@ -35,10 +43,10 @@ export default async function Page({ params }: { params: { slug?: string[] } })
35
43
href = { `https://github.com/gitbutlerapp/gitbutler-docs/issues/new?label=docs&title=Feedback+for+page+"${ page . file . flattenedPath } "` }
36
44
target = "_blank"
37
45
rel = "noreferrer noopener"
38
- className = "rounded-md text-neutral-500 dark:text-neutral-400 dark:bg-neutral-900 border border-neutral-300/50 text-sm py-1 dark:border- neutral-700 flex justify-center items-center gap-2 hover :bg-neutral-100 transition duration-300 dark:hover:bg-neutral-950 group "
46
+ className = "group flex items-center justify-center gap-2 rounded-md border border-neutral-300/50 py-1 text-sm text- neutral-500 transition duration-300 hover:bg-neutral-100 dark:border-neutral-700 dark :bg-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-950"
39
47
>
40
48
< svg
41
- className = "size-4 transition ease-[var(--ease-spring-3)] duration-500 group-hover:animate-[var(--animation-bounce)]"
49
+ className = "size-4 transition duration-500 ease-[var(--ease-spring-3)] group-hover:animate-[var(--animation-bounce)]"
42
50
xmlns = "http://www.w3.org/2000/svg"
43
51
viewBox = "0 0 256 256"
44
52
>
@@ -65,46 +73,59 @@ export default async function Page({ params }: { params: { slug?: string[] } })
65
73
</ >
66
74
)
67
75
68
- const time = await getGithubLastEdit ( {
69
- owner : "gitbutlerapp" ,
70
- repo : "gitbutler-docs" ,
71
- path : join ( "content/docs/" , page . file . path )
72
- } )
73
-
74
- const MDX = page . data . exports . default
75
-
76
76
return (
77
77
< DocsPage
78
- toc = { page . data . exports . toc }
79
- full = { page . data . full ?? false }
80
- lastUpdate = { time ?? undefined }
78
+ toc = { page . data . toc }
79
+ full = { page . data . full }
81
80
tableOfContent = { {
81
+ style : "clerk" ,
82
+ single : false ,
83
+ footer
84
+ } }
85
+ lastUpdate = { page . data . lastModified }
86
+ tableOfContentPopover = { {
82
87
footer
83
88
} }
84
- tableOfContentPopover = { { footer } }
85
89
>
86
- < RollButton percentage = { 0.3 } />
90
+ < DocsTitle > { page . data . title } </ DocsTitle >
91
+ < DocsDescription > { page . data . description } </ DocsDescription >
87
92
< DocsBody >
88
- < h1 > { page . data . title } </ h1 >
89
- < MDX />
93
+ < page . data . body
94
+ components = { {
95
+ ...defaultComponents ,
96
+ Popup,
97
+ PopupContent,
98
+ PopupTrigger,
99
+ Tabs,
100
+ Tab,
101
+ TypeTable,
102
+ Accordion,
103
+ Accordions,
104
+ ImageSection,
105
+ blockquote : Callout as unknown as FC < ComponentProps < "blockquote" > > ,
106
+ APIPage : openapi . APIPage
107
+ } }
108
+ />
90
109
</ DocsBody >
91
110
</ DocsPage >
92
111
)
93
112
}
94
113
95
- export async function generateStaticParams ( ) {
96
- return getPages ( ) . map ( ( page ) => ( {
97
- slug : page . slugs
98
- } ) )
114
+ export function generateStaticParams ( ) : Param [ ] {
115
+ return utils . getPages ( ) . map ( ( page ) => {
116
+ return {
117
+ slug : page . slugs
118
+ }
119
+ } )
99
120
}
100
121
101
122
export function generateMetadata ( { params } : { params : { slug ?: string [ ] } } ) {
102
- const page = getPage ( params . slug )
123
+ const page = utils . getPage ( params . slug )
103
124
104
- if ( page == null ) notFound ( )
125
+ if ( ! page ) notFound ( )
105
126
106
127
return {
107
128
title : page . data . title ,
108
129
description : page . data . description
109
- } satisfies Metadata
130
+ }
110
131
}
0 commit comments