mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
Feature / Refactor ## What is the current behavior? Data API docs live at the `/api` route as a standalone page. Old links point to the previous location. ## What is the new behavior? Data API docs are moved to the integrations section with a dedicated docs tab and settings tab. Old links are cleaned up, a mobile menu is added for data API docs navigation, and minor code review fixes are applied. ## Additional context Resolves FE-2517 ## Summary by CodeRabbit * **New Features** * Revamped API docs UI with reusable section layout, language toggle (JS/Bash), API key selection, and improved code snippets * Added Data API docs tab, mobile navigation, and dedicated loading/error/disabled states * **Navigation Updates** * Moved API docs and related links into the Integrations/Data API area and added redirects to new routes * Updated various internal links to the new Data API settings and overview locations * **Tests** * Added comprehensive unit tests for Data API utilities
84 lines
2.4 KiB
TypeScript
84 lines
2.4 KiB
TypeScript
import Link from 'next/link'
|
|
import { cn } from 'ui'
|
|
|
|
import { ProductMenuGroup } from '@/components/ui/ProductMenu/ProductMenu.types'
|
|
|
|
export const DocsMenu = ({
|
|
menu,
|
|
activePage,
|
|
}: {
|
|
menu: Array<ProductMenuGroup>
|
|
activePage?: string
|
|
}) => {
|
|
return (
|
|
<nav className="space-y-6 text-xs">
|
|
{menu.map((group, idx) => (
|
|
<div key={group.key || group.title || idx}>
|
|
{group.title && (
|
|
<div className="heading-meta mb-2 text-foreground-lighter">{group.title}</div>
|
|
)}
|
|
<div className="space-y-2">
|
|
{group.items.map((item) => {
|
|
const isActive = item.pages
|
|
? item.pages.includes(activePage ?? '')
|
|
: activePage === item.key
|
|
const isDisabled = !!item.disabled
|
|
const content = (
|
|
<span
|
|
className={cn(
|
|
'flex items-center',
|
|
isActive ? 'text-foreground' : 'text-foreground-light hover:text-foreground'
|
|
)}
|
|
>
|
|
<span className="truncate">{item.name}</span>
|
|
{item.rightIcon && (
|
|
<span className="ml-auto text-foreground-lighter">{item.rightIcon}</span>
|
|
)}
|
|
</span>
|
|
)
|
|
|
|
if (isDisabled) {
|
|
return (
|
|
<span
|
|
key={item.key}
|
|
className="block pointer-events-none opacity-50"
|
|
aria-disabled="true"
|
|
tabIndex={-1}
|
|
>
|
|
{content}
|
|
</span>
|
|
)
|
|
}
|
|
|
|
if (item.isExternal) {
|
|
return (
|
|
<a
|
|
key={item.key}
|
|
href={item.url}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block"
|
|
>
|
|
{content}
|
|
</a>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Link
|
|
key={item.key}
|
|
href={item.url}
|
|
className="block"
|
|
aria-current={isActive ? 'page' : undefined}
|
|
>
|
|
{content}
|
|
</Link>
|
|
)
|
|
})}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</nav>
|
|
)
|
|
}
|