|
1 | | -'use client' |
| 1 | +import { redirect } from 'next/navigation' |
2 | 2 |
|
3 | | -import dynamic from 'next/dynamic' |
4 | | -import NextLink from 'next/link' |
5 | | -import { notFound } from 'next/navigation' |
6 | | -import React from 'react' |
7 | | - |
8 | | -import type { Doc } from '@/types/docs' |
9 | | - |
10 | | -import { sections } from '@/components/docs/doc-sidebar' |
11 | | -import { Mdx } from '@/components/docs/mdx/mdx-components' |
12 | 3 | import { getDocsByCategory } from '@/lib/docs' |
13 | 4 |
|
14 | | -const DocNavigation = ({ category }: { category: string }) => { |
15 | | - const currentIndex = sections.findIndex((s) => s.href === `/docs/${category}`) |
16 | | - const prevSection = currentIndex > 0 ? sections[currentIndex - 1] : null |
17 | | - const nextSection = |
18 | | - currentIndex < sections.length - 1 ? sections[currentIndex + 1] : null |
19 | | - |
20 | | - return ( |
21 | | - <div className="flex justify-between items-center pt-8 mt-8 border-t"> |
22 | | - {prevSection && ( |
23 | | - <NextLink |
24 | | - href={prevSection.href} |
25 | | - className="flex items-center gap-2 px-4 py-2 rounded-lg bg-white/5 text-gray-300 hover:bg-white/10 hover:text-white transition-colors" |
26 | | - > |
27 | | - <svg |
28 | | - xmlns="http://www.w3.org/2000/svg" |
29 | | - className="h-5 w-5" |
30 | | - viewBox="0 0 24 24" |
31 | | - fill="none" |
32 | | - stroke="currentColor" |
33 | | - strokeWidth="2" |
34 | | - strokeLinecap="round" |
35 | | - strokeLinejoin="round" |
36 | | - > |
37 | | - <path d="M19 12H5M12 19l-7-7 7-7" /> |
38 | | - </svg> |
39 | | - <span className="font-medium">{prevSection.title}</span> |
40 | | - </NextLink> |
41 | | - )} |
42 | | - {nextSection && ( |
43 | | - <NextLink |
44 | | - href={nextSection.href} |
45 | | - className="flex items-center gap-2 px-4 py-2 rounded-lg bg-white/5 text-gray-300 hover:bg-white/10 hover:text-white transition-colors ml-auto" |
46 | | - > |
47 | | - <span className="font-medium">{nextSection.title}</span> |
48 | | - <svg |
49 | | - xmlns="http://www.w3.org/2000/svg" |
50 | | - className="h-5 w-5" |
51 | | - viewBox="0 0 24 24" |
52 | | - fill="none" |
53 | | - stroke="currentColor" |
54 | | - strokeWidth="2" |
55 | | - strokeLinecap="round" |
56 | | - strokeLinejoin="round" |
57 | | - > |
58 | | - <path d="M5 12h14M12 5l7 7-7 7" /> |
59 | | - </svg> |
60 | | - </NextLink> |
61 | | - )} |
62 | | - </div> |
63 | | - ) |
64 | | -} |
65 | | - |
66 | 5 | interface CategoryPageProps { |
67 | 6 | params: { category: string } |
68 | 7 | } |
69 | 8 |
|
70 | | -const DocPage = ({ doc }: { doc: Doc }) => { |
71 | | - return ( |
72 | | - <article className="prose dark:prose-invert prose-compact [&_h1]:scroll-mt-24 [&_h2]:scroll-mt-24 [&_h3]:scroll-mt-24 max-w-none overflow-x-auto"> |
73 | | - <Mdx code={doc.body.code} /> |
74 | | - |
75 | | - {React.createElement( |
76 | | - dynamic(() => |
77 | | - import(`@/content/${doc.category}/_cta.mdx`).catch(() => () => null) |
78 | | - ) |
79 | | - )} |
80 | | - </article> |
81 | | - ) |
82 | | -} |
83 | | - |
84 | 9 | export default function CategoryPage({ params }: CategoryPageProps) { |
85 | 10 | const docs = getDocsByCategory(params.category) |
86 | 11 |
|
87 | 12 | if (!docs.length) { |
88 | | - return notFound() |
| 13 | + redirect('/docs') |
89 | 14 | } |
90 | 15 |
|
91 | | - // Sort by order field |
| 16 | + // Sort by order field and redirect to first doc |
92 | 17 | const sortedDocs = [...docs].sort((a, b) => (a.order ?? 0) - (b.order ?? 0)) |
| 18 | + const firstDoc = sortedDocs[0] |
93 | 19 |
|
94 | | - return ( |
95 | | - <div className="max-w-3xl mx-auto grid divide-y divide-border [&>*]:py-12 first:[&>*]:pt-0 last:[&>*]:pb-0"> |
96 | | - {sortedDocs.map((doc) => ( |
97 | | - <DocPage key={doc.slug} doc={doc} /> |
98 | | - ))} |
99 | | - |
100 | | - <DocNavigation category={params.category} /> |
101 | | - </div> |
102 | | - ) |
| 20 | + redirect(`/docs/${params.category}/${firstDoc.slug}`) |
103 | 21 | } |
0 commit comments