Skip to content

Commit 9db5cfd

Browse files
authored
improvements: Content structure + navigation fix (#704)
* feat: Add pagination component and update documentation layout * Add performance documentation and optimization solutions - Created navigation and performance overview documentation in `docs-v3/content/docs/7.performance/1.performance.md`. - Added optimization solutions documentation in `docs-v3/content/docs/7.performance/2.solutions.md`. - Introduced extensions documentation for the Boost package in `docs-v3/content/docs/8.boost/1.boost.md`. - Added testing guide documentation in `docs-v3/content/docs/9.testing/1.testing.md`. - Updated navigation files for performance, extensions, and testing sections. - Fixed link in main documentation index to point to the correct quickstart page. * feat: Add Nuxt Content configuration with markdown highlighting support * fix: Update Git command display in CtaSection component * feat: Update resource links in footer for improved navigation * feat: Update button components and styles for consistency across documentation pages * feat: Replace HeroButton with AppButton component across multiple files for consistency and improved styling * feat: Make header sticky in MobileSidebarOverlay for improved navigation * feat: Add search functionality to WebsiteNavbar for documentation pages
1 parent 48d4d88 commit 9db5cfd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+382
-336
lines changed
1.59 MB
Binary file not shown.

docs-v3/components/MobileSidebarOverlay.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
@click.stop
1414
@touchmove.stop
1515
>
16-
<div class="flex items-center justify-between px-4 py-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0">
16+
<div class="sticky top-0 z-10 flex items-center justify-between px-4 py-4 border-b border-gray-200 dark:border-gray-700 flex-shrink-0 bg-white dark:bg-gray-900">
1717
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">{{ title }}</h2>
1818
<button
1919
@click.stop="$emit('close')"

docs-v3/components/case-studies/CaseStudiesCta.vue

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,29 @@
1414
Start your project today and become our next case study.
1515
</p>
1616
<div class="flex flex-col sm:flex-row gap-4 justify-center">
17-
<NuxtLink
18-
to="/docs"
19-
class="inline-flex items-center justify-center px-8 py-4 bg-gradient-to-r from-red-500 to-red-600 text-white hover:from-red-600 hover:to-red-700 font-semibold rounded-xl transition-all duration-300 text-lg shadow-lg shadow-red-500/20 hover:shadow-red-500/30"
17+
<AppButton
18+
variant="primary"
19+
href="/docs"
20+
:icon="BookOpenIcon"
21+
:is-nuxt-link="true"
22+
:external="false"
2023
>
21-
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
22-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.746 0 3.332.477 4.5 1.253v13C19.832 18.477 18.246 18 16.5 18c-1.746 0-3.332.477-4.5 1.253" />
23-
</svg>
2424
Get Started with Restify
25-
</NuxtLink>
26-
<a
25+
</AppButton>
26+
<AppButton
27+
variant="secondary"
2728
href="https://www.binarcode.com/recent-work"
28-
target="_blank"
29-
rel="noopener noreferrer"
30-
class="inline-flex items-center justify-center px-8 py-4 bg-gray-100 dark:bg-gray-800/50 border border-gray-300 dark:border-gray-700/50 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700/50 hover:text-gray-900 dark:hover:text-white font-semibold rounded-xl transition-all duration-300 text-lg backdrop-blur-sm"
29+
:icon="BriefcaseIcon"
30+
:show-external-icon="true"
3131
>
32-
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
33-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16l3-3 3 3 3-3 3 3V5a2 2 0 00-2-2z" />
34-
</svg>
3532
Recent Projects
36-
</a>
33+
</AppButton>
3734
</div>
3835
</div>
3936
</div>
4037
</template>
38+
39+
<script setup lang="ts">
40+
import { BookOpenIcon, BriefcaseIcon } from '@heroicons/vue/24/outline'
41+
import AppButton from '~/components/ui/AppButton.vue'
42+
</script>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<template>
2+
<nav
3+
v-if="surround && (surround[0] || surround[1])"
4+
class="mt-12 pt-6 border-t border-gray-200 dark:border-gray-700"
5+
>
6+
<div class="flex items-center justify-between gap-4">
7+
<NuxtLink
8+
v-if="surround[0]"
9+
:to="surround[0].path"
10+
class="group flex-1 flex items-center gap-3 p-4 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-all"
11+
>
12+
<ChevronLeftIcon
13+
class="w-5 h-5 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 transition-colors"
14+
/>
15+
<div class="min-w-0">
16+
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">Previous</div>
17+
<div
18+
class="text-sm font-medium text-gray-900 dark:text-white truncate transition-colors"
19+
>
20+
{{ surround[0].title }}
21+
</div>
22+
</div>
23+
</NuxtLink>
24+
25+
<div v-else class="flex-1"></div>
26+
27+
<NuxtLink
28+
v-if="surround[1]"
29+
:to="surround[1].path"
30+
class="group flex-1 flex items-center justify-end gap-3 p-4 rounded-lg border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-all text-right"
31+
>
32+
<div class="min-w-0">
33+
<div class="text-xs text-gray-500 dark:text-gray-400 mb-1">Next</div>
34+
<div
35+
class="text-sm font-medium text-gray-900 dark:text-white truncate transition-colors"
36+
>
37+
{{ surround[1].title }}
38+
</div>
39+
</div>
40+
<ChevronRightIcon
41+
class="w-5 h-5 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 transition-colors"
42+
/>
43+
</NuxtLink>
44+
45+
<div v-else class="flex-1"></div>
46+
</div>
47+
</nav>
48+
</template>
49+
50+
<script setup lang="ts">
51+
import { ChevronLeftIcon, ChevronRightIcon } from '@heroicons/vue/24/outline'
52+
53+
const route = useRoute()
54+
55+
const { data: surround } = await useAsyncData(`surround-${route.path}`, () => {
56+
return queryCollectionItemSurroundings('content', route.path)
57+
})
58+
</script>

docs-v3/components/docs/DocsSidebar.vue

Lines changed: 26 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<nav class="fixed top-16 left-0 w-64 h-[calc(100vh-4rem)] overflow-y-auto px-4 py-6 bg-gray-50 dark:bg-gray-800/50 border-r border-gray-200 dark:border-gray-700">
44
<div class="space-y-6">
55
<NavigationSection
6-
v-for="section in docsNavigationSections"
6+
v-for="section in navigationSections"
77
:key="section.title"
88
:title="section.title"
99
:items="section.items"
@@ -22,7 +22,7 @@
2222
>
2323
<div class="space-y-6">
2424
<NavigationSection
25-
v-for="section in docsNavigationSections"
25+
v-for="section in navigationSections"
2626
:key="section.title"
2727
:title="section.title"
2828
:items="section.items"
@@ -38,83 +38,30 @@
3838
<script setup lang="ts">
3939
const INITIALLY_COLLAPSED = ['Performance', 'Extensions', 'Testing']
4040
41-
const docsNavigationSections = [
42-
{
43-
title: "Getting Started",
44-
items: [
45-
{ title: "Quick Start", path: "/docs/quickstart" },
46-
]
47-
},
48-
{
49-
title: "Authentication",
50-
items: [
51-
{ title: "Authentication", path: "/docs/auth/authentication" },
52-
{ title: "Authorization", path: "/docs/auth/authorization" },
53-
{ title: "Profile Management", path: "/docs/auth/profile" }
54-
]
55-
},
56-
{
57-
title: "API Resources",
58-
items: [
59-
{ title: "Basic Repositories", path: "/docs/api/repositories-basic" },
60-
{ title: "Repositories", path: "/docs/api/repositories" },
61-
{ title: "Advanced Repositories", path: "/docs/api/repositories-advanced" },
62-
{ title: "Repository Generation", path: "/docs/api/repository-generation" },
63-
{ title: "Fields", path: "/docs/api/fields" },
64-
{ title: "Relations", path: "/docs/api/relations" },
65-
{ title: "REST Methods", path: "/docs/api/rest-methods" },
66-
{ title: "Validation Methods", path: "/docs/api/validation-methods" },
67-
{ title: "Actions", path: "/docs/api/actions" },
68-
{ title: "Getters", path: "/docs/api/getters" },
69-
{ title: "Serializer", path: "/docs/api/serializer" }
70-
]
71-
},
72-
{
73-
title: "Search & Filtering",
74-
items: [
75-
{ title: "Basic Filters", path: "/docs/search/basic-filters" },
76-
{ title: "Advanced Filters", path: "/docs/search/advanced-filters" },
77-
{ title: "Sorting", path: "/docs/search/sorting" }
78-
]
79-
},
80-
{
81-
title: "GraphQL",
82-
items: [
83-
{ title: "GraphQL Overview", path: "/docs/graphql/graphql" },
84-
{ title: "Schema Generation", path: "/docs/graphql/graphql-generation" }
85-
]
86-
},
87-
{
88-
title: "MCP Integration",
89-
items: [
90-
{ title: "MCP Server", path: "/docs/mcp/mcp" },
91-
{ title: "MCP Repositories", path: "/docs/mcp/repositories" },
92-
{ title: "MCP Fields", path: "/docs/mcp/fields" },
93-
{ title: "MCP Getters", path: "/docs/mcp/getters" },
94-
{ title: "JSON Schema Converter", path: "/docs/mcp/json-schema-converter" },
95-
{ title: "MCP Actions", path: "/docs/mcp/actions" }
96-
]
97-
},
98-
{
99-
title: "Performance",
100-
items: [
101-
{ title: "Performance Overview", path: "/docs/performance/performance" },
102-
{ title: "Optimization Solutions", path: "/docs/performance/solutions" }
103-
]
104-
},
105-
{
106-
title: "Extensions",
107-
items: [
108-
{ title: "Boost Package", path: "/docs/boost/boost" }
109-
]
110-
},
111-
{
112-
title: "Testing",
113-
items: [
114-
{ title: "Testing Guide", path: "/docs/testing/testing" }
115-
]
116-
}
117-
]
41+
// Fetch docs navigation from Nuxt Content
42+
const { data: navigation } = await useAsyncData('docs-navigation', () =>
43+
queryCollectionNavigation('content')
44+
)
45+
46+
// Transform navigation tree to sidebar format
47+
const navigationSections = computed(() => {
48+
if (!navigation.value) return []
49+
50+
// Find the docs section in the navigation
51+
const docsNav = navigation.value.find(item => item.path === '/docs')
52+
if (!docsNav?.children) return []
53+
54+
// Transform each section (folder) into sidebar format
55+
return docsNav.children
56+
.filter(section => section.children && section.children.length > 0)
57+
.map(section => ({
58+
title: section.title,
59+
items: section.children.map(item => ({
60+
title: item.title,
61+
path: item.path
62+
}))
63+
}))
64+
})
11865
11966
const isMobileMenuOpen = inject('isMobileMenuOpen', ref(false))
12067
const toggleMobileMenu = inject('toggleMobileMenu', () => {})

docs-v3/components/templates/TemplatesCustomCta.vue

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
<p class="text-gray-400 mb-6">
66
Our team can build a custom Laravel Restify template tailored specifically to your project needs.
77
</p>
8-
<a
8+
<AppButton
9+
variant="primary"
10+
size="md"
911
href="https://www.binarcode.com/estimate-project"
10-
target="_blank"
11-
rel="noopener noreferrer"
12-
class="inline-flex items-center px-6 py-3 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-all duration-200"
12+
:icon="WrenchScrewdriverIcon"
13+
:show-external-icon="true"
1314
>
1415
Get Your Custom Template
15-
<ArrowTopRightOnSquareIcon class="w-4 h-4 ml-2" />
16-
</a>
16+
</AppButton>
1717
</div>
1818
</div>
1919
</template>
2020

2121
<script setup lang="ts">
22-
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline'
22+
import { WrenchScrewdriverIcon } from '@heroicons/vue/24/outline'
23+
import AppButton from '~/components/ui/AppButton.vue'
2324
</script>

docs-v3/components/templates/TemplatesHeader.vue

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,29 @@
88
</p>
99

1010
<div class="flex flex-col sm:flex-row gap-4 justify-center items-center">
11-
<a
11+
<AppButton
12+
variant="primary"
13+
size="md"
1214
href="https://restifytemplates.com/"
13-
target="_blank"
14-
rel="noopener noreferrer"
15-
class="inline-flex items-center px-6 py-3 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-all duration-200"
15+
:icon="RocketLaunchIcon"
16+
:show-external-icon="true"
1617
>
1718
Browse All Templates
18-
<ArrowTopRightOnSquareIcon class="w-4 h-4 ml-2" />
19-
</a>
20-
<a
19+
</AppButton>
20+
<AppButton
21+
variant="secondary"
22+
size="md"
2123
href="https://www.binarcode.com/estimate-project"
22-
target="_blank"
23-
rel="noopener noreferrer"
24-
class="inline-flex items-center px-6 py-3 bg-gray-100 dark:bg-gray-800/50 border border-gray-300 dark:border-gray-700 text-gray-700 dark:text-gray-300 hover:border-gray-400 dark:hover:border-gray-600 hover:bg-gray-200 dark:hover:bg-gray-800 font-medium rounded-lg transition-all duration-200"
24+
:icon="WrenchScrewdriverIcon"
25+
:show-external-icon="true"
2526
>
26-
Get Your Custom Template
27-
<ArrowTopRightOnSquareIcon class="w-4 h-4 ml-2" />
28-
</a>
27+
Get Custom Template
28+
</AppButton>
2929
</div>
3030
</div>
3131
</template>
3232

3333
<script setup lang="ts">
34-
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline'
34+
import { RocketLaunchIcon, WrenchScrewdriverIcon } from '@heroicons/vue/24/outline'
35+
import AppButton from '~/components/ui/AppButton.vue'
3536
</script>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<template>
2+
<NuxtLink
3+
v-if="isNuxtLink"
4+
:to="href"
5+
:class="buttonClasses"
6+
>
7+
<div v-if="variant === 'primary'" class="absolute inset-0 bg-gradient-to-r from-blue-600 to-cyan-700 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
8+
<component v-if="icon" :is="icon" class="relative z-10 w-5 h-5 group-hover:rotate-12 transition-transform duration-300" />
9+
<span class="relative z-10"><slot /></span>
10+
<ArrowTopRightOnSquareIcon v-if="showExternalIcon && !isNuxtLink" class="relative z-10 w-4 h-4 ml-1" />
11+
</NuxtLink>
12+
<a
13+
v-else
14+
:href="href"
15+
:target="external ? '_blank' : undefined"
16+
:rel="external ? 'noopener noreferrer' : undefined"
17+
:class="buttonClasses"
18+
>
19+
<div v-if="variant === 'primary'" class="absolute inset-0 bg-gradient-to-r from-blue-600 to-cyan-700 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
20+
<component v-if="icon" :is="icon" class="relative z-10 w-5 h-5 group-hover:rotate-12 transition-transform duration-300" />
21+
<span class="relative z-10"><slot /></span>
22+
</a>
23+
</template>
24+
25+
<script setup lang="ts">
26+
import type { Component } from 'vue'
27+
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/outline'
28+
29+
type ButtonVariant = 'primary' | 'secondary'
30+
type ButtonSize = 'sm' | 'md' | 'lg'
31+
32+
interface Props {
33+
variant?: ButtonVariant
34+
size?: ButtonSize
35+
href: string
36+
icon?: Component
37+
isNuxtLink?: boolean
38+
external?: boolean
39+
showExternalIcon?: boolean
40+
}
41+
42+
const props = withDefaults(defineProps<Props>(), {
43+
variant: 'primary',
44+
size: 'lg',
45+
isNuxtLink: false,
46+
external: true,
47+
showExternalIcon: false
48+
})
49+
50+
const SIZE_CLASSES: Record<ButtonSize, string> = {
51+
sm: 'px-4 py-2 text-sm min-h-[40px]',
52+
md: 'px-5 py-3 text-base min-h-[48px]',
53+
lg: 'px-6 sm:px-8 py-4 text-base sm:text-lg min-h-[56px]'
54+
}
55+
56+
const BASE_CLASSES = 'cursor-pointer group relative inline-flex items-center justify-center gap-3 font-semibold rounded-full overflow-hidden transition-all duration-300 hover:scale-105'
57+
58+
const VARIANT_STYLES: Record<ButtonVariant, string> = {
59+
primary: 'text-white bg-gradient-to-r from-blue-500 to-cyan-600 hover:shadow-2xl hover:shadow-blue-500/25',
60+
secondary: 'text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-white/5 border border-gray-300 dark:border-white/10 backdrop-blur-sm hover:bg-gray-200 dark:hover:bg-white/10 hover:border-gray-400 dark:hover:border-white/20'
61+
}
62+
63+
const buttonClasses = computed(() => `${BASE_CLASSES} ${SIZE_CLASSES[props.size]} ${VARIANT_STYLES[props.variant]}`)
64+
</script>

0 commit comments

Comments
 (0)