kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat(web): finesse features section
rodzic
422da87f1c
commit
52302243cd
|
@ -2,14 +2,10 @@ import Link from 'next/link'
|
|||
|
||||
import { DotsSection } from '@/components/dots-section'
|
||||
import { ExampleAgenticConfigs } from '@/components/example-agentic-configs'
|
||||
import { Features } from '@/components/features'
|
||||
import { GitHubStarCounter } from '@/components/github-star-counter'
|
||||
import { SupplySideCTA } from '@/components/supply-side-cta'
|
||||
import {
|
||||
calendarBookingUrl,
|
||||
docsUrl,
|
||||
githubUrl,
|
||||
twitterUrl
|
||||
} from '@/lib/config'
|
||||
import { githubUrl, twitterUrl } from '@/lib/config'
|
||||
|
||||
export default function MCPAuthorsPage() {
|
||||
return (
|
||||
|
@ -64,147 +60,10 @@ export default function MCPAuthorsPage() {
|
|||
{/* Features section */}
|
||||
<section className='flex flex-col gap-8 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Production-Ready and Extremely Flexible
|
||||
Production-Ready MCP Gateway
|
||||
</h2>
|
||||
|
||||
<div className='grid gap-6 max-w-2xl'>
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Auth
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Ship to production fast with Agentic's free, built-in
|
||||
authentication. Email & password, OAuth, GitHub, Google, Twitter,
|
||||
etc – if your origin API requires OAuth credentials, Agentic
|
||||
likely already supports it, and if not,{' '}
|
||||
<Link
|
||||
href={calendarBookingUrl}
|
||||
target='_blank'
|
||||
rel='noopener'
|
||||
className='link'
|
||||
>
|
||||
let me know
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Stripe Billing
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Charge for your MCP products with a flexible, declarative pricing
|
||||
model built on top of Stripe. Agentic supports almost any
|
||||
combination of fixed and{' '}
|
||||
<span className='font-semibold'>usage-based billing</span> models,
|
||||
both at the MCP level, at the tool-call level, and at the custom
|
||||
metric level (e.g., tokens, image transformations, etc).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Support both MCP and HTTP
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
All agentic products support being used both as a standard MCP
|
||||
server <em>and</em> as an extremely simple HTTP API. MCP is
|
||||
important for interop, discoverability, and future-proofing,
|
||||
whereas being able to call your agentic tools via simple{' '}
|
||||
<em>HTTP POST</em> requests makes tool use easy to debug and makes
|
||||
integration with existing LLM tool calling patterns a breeze. With
|
||||
Agentic, you get the best of both worlds, including future support
|
||||
for unreleased MCP features and related specs.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
API keys
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
When a customer subscribes to your product, they're given a unique
|
||||
API key. MCP URLs are appended with this API key to correlate
|
||||
usage with their subscription. Customer HTTP tool calls use the
|
||||
same API key as a standard HTTP <em>Authorization</em> header.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Rate-limiting
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
All agentic products are protected by durable rate-limiting built
|
||||
on top of Cloudflare's global infrastructure. Customize the
|
||||
default rate-limits, change them based on a customer's pricing
|
||||
plan, or create custom tool-specific overrides. REST assured that
|
||||
your origin API will be safe behind Agentic's robust API gateway.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Caching
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Opt-in to caching with familiar <em>cache-control</em> and{' '}
|
||||
<em>stale-while-revalidate</em> options. MCP tool calls include
|
||||
caching information in their <em>_meta</em> fields, providing
|
||||
parity with standard HTTP headers. All caching takes place in
|
||||
Cloudflare's global edge cache, and caching will only be enabled
|
||||
if you choose to enable it for your product or individual tools.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Analytics
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Agentic tracks all tool calls for usage-based billing and
|
||||
analytics at a fine-grained level, so you can drill in and deeply
|
||||
understand how your customers are using your product.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
Versioning
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
Just like Vercel, Agentic uses immutable deployments, so every
|
||||
time you make a change to your product's config, pricing, or docs,
|
||||
a unique preview deployment is created for that change. This
|
||||
enables instant rollbacks if there are problems with a deployment.
|
||||
Publishing deployments publicly uses semantic versioning (
|
||||
<em>semver</em>), so your customers can choose how to handle
|
||||
breaking changes.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex flex-col gap-2'>
|
||||
<h4 className='text-center text-balance text-lg font-heading'>
|
||||
That's just the start
|
||||
</h4>
|
||||
|
||||
<p className='text-sm'>
|
||||
<Link href={docsUrl} className='link'>
|
||||
Check out our docs
|
||||
</Link>{' '}
|
||||
for more details on Agentic's MCP API gateway.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Features />
|
||||
</section>
|
||||
|
||||
{/* Open source section */}
|
||||
|
@ -214,7 +73,6 @@ export default function MCPAuthorsPage() {
|
|||
</h2>
|
||||
|
||||
<p className=''>
|
||||
Open source is very dear to my heart, and I couldn't be happier that
|
||||
Agentic is fully OSS. It's written in{' '}
|
||||
<span className='font-semibold'>TypeScript</span> and has a small but
|
||||
vibrant developer community.{' '}
|
||||
|
@ -242,13 +100,15 @@ export default function MCPAuthorsPage() {
|
|||
</section>
|
||||
|
||||
{/* CTA section */}
|
||||
<section className='flex flex-col gap-12 mb-16'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Deploy Your MCP Today
|
||||
</h2>
|
||||
<DotsSection className='mb-16'>
|
||||
<div className='flex flex-col gap-12 z-10'>
|
||||
<h2 className='text-center text-balance leading-snug md:leading-none text-3xl font-heading'>
|
||||
Deploy Your MCP Today
|
||||
</h2>
|
||||
|
||||
<SupplySideCTA variant='github-2' />
|
||||
</section>
|
||||
<SupplySideCTA variant='github-2' />
|
||||
</div>
|
||||
</DotsSection>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -105,7 +105,6 @@ export default async function TheBestDamnLandingPageEver() {
|
|||
</h2>
|
||||
|
||||
<p className=''>
|
||||
Open source is very dear to my heart, and I couldn't be happier that
|
||||
Agentic is fully OSS. It's written in{' '}
|
||||
<span className='font-semibold'>TypeScript</span> and has a small but
|
||||
vibrant developer community.{' '}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { docsMarketplaceUrl } from '@/lib/config'
|
|||
|
||||
export function DemandSideCTA() {
|
||||
return (
|
||||
<div className='flex justify-center items-center gap-8'>
|
||||
<div className='flex justify-center items-center gap-12'>
|
||||
<HeroButton asChild className='h-full'>
|
||||
<Link href='/marketplace' className='font-mono'>
|
||||
gotoTools();
|
||||
|
|
|
@ -0,0 +1,336 @@
|
|||
'use client'
|
||||
|
||||
import type { ComponentType, ReactNode } from 'react'
|
||||
import {
|
||||
ChartNoAxesCombinedIcon,
|
||||
CheckCheckIcon,
|
||||
CreditCardIcon,
|
||||
DatabaseZapIcon,
|
||||
HistoryIcon,
|
||||
KeyRoundIcon,
|
||||
ShieldCheckIcon,
|
||||
TextSelectIcon,
|
||||
UserIcon
|
||||
} from 'lucide-react'
|
||||
import {
|
||||
motion,
|
||||
type MotionValue,
|
||||
useMotionTemplate,
|
||||
useMotionValue
|
||||
} from 'motion/react'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { calendarBookingUrl, docsUrl } from '@/lib/config'
|
||||
|
||||
import { GridPattern } from './grid-pattern'
|
||||
|
||||
type Feature = {
|
||||
name: string
|
||||
description: ReactNode
|
||||
icon: ComponentType<{ className?: string }>
|
||||
pattern: Omit<GridPattern, 'width' | 'height' | 'x'>
|
||||
href?: string
|
||||
}
|
||||
|
||||
const FEATURES: Feature[] = [
|
||||
{
|
||||
name: 'Auth',
|
||||
description: (
|
||||
<>
|
||||
Ship to production fast with Agentic's free, built-in authentication.
|
||||
Email & password, OAuth, GitHub, Google, Twitter, etc – if your origin
|
||||
API requires OAuth credentials, Agentic likely already supports it, and
|
||||
if not,{' '}
|
||||
<Link
|
||||
href={calendarBookingUrl}
|
||||
target='_blank'
|
||||
rel='noopener'
|
||||
className='link'
|
||||
>
|
||||
let me know
|
||||
</Link>
|
||||
.
|
||||
</>
|
||||
),
|
||||
icon: UserIcon,
|
||||
pattern: {
|
||||
y: 16,
|
||||
squares: [
|
||||
[0, 1],
|
||||
[1, 3]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Stripe Billing',
|
||||
description: (
|
||||
<>
|
||||
Charge for your MCP products with a flexible, declarative pricing model
|
||||
built on top of Stripe. Agentic supports almost any combination of fixed
|
||||
and <span className='font-semibold'>usage-based billing</span> models,
|
||||
both at the MCP level, at the tool-call level, and at the custom metric
|
||||
level (e.g., tokens, image transformations, etc).
|
||||
</>
|
||||
),
|
||||
icon: CreditCardIcon,
|
||||
pattern: {
|
||||
y: -6,
|
||||
squares: [
|
||||
[-1, 2],
|
||||
[1, 3]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Support both MCP and HTTP',
|
||||
description: (
|
||||
<>
|
||||
All agentic products support being used both as a standard MCP server{' '}
|
||||
<em>and</em> as an extremely simple HTTP API. MCP is important for
|
||||
interop and future-proofing, whereas being able to call your agentic
|
||||
tools via simple <em>HTTP POST</em> requests makes tool use easy to
|
||||
debug and makes integration with existing LLM tool calling patterns a
|
||||
breeze.
|
||||
</>
|
||||
),
|
||||
icon: CheckCheckIcon,
|
||||
pattern: {
|
||||
y: 32,
|
||||
squares: [
|
||||
[0, 2],
|
||||
[1, 4]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'API Keys',
|
||||
description: (
|
||||
<>
|
||||
When a customer subscribes to your product, they're given a unique API
|
||||
key. MCP URLs are appended with this API key to correlate usage with
|
||||
their subscription. Customer HTTP tool calls use the same API key as a
|
||||
standard HTTP <em>Authorization</em> header.
|
||||
</>
|
||||
),
|
||||
icon: KeyRoundIcon,
|
||||
pattern: {
|
||||
y: 22,
|
||||
squares: [[0, 1]]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Rate-limiting',
|
||||
description: (
|
||||
<>
|
||||
All agentic products are protected by durable rate-limiting built on top
|
||||
of Cloudflare's global infrastructure. Customize the default
|
||||
rate-limits, change them based on a customer's pricing plan, or create
|
||||
custom tool-specific overrides. REST assured that your origin API will
|
||||
be safe behind Agentic's API gateway.
|
||||
</>
|
||||
),
|
||||
icon: ShieldCheckIcon,
|
||||
pattern: {
|
||||
y: 2,
|
||||
squares: [
|
||||
[-2, 3],
|
||||
[1, 4]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Caching',
|
||||
description: (
|
||||
<>
|
||||
Opt-in to caching with familiar <em>cache-control</em> and{' '}
|
||||
<em>stale-while-revalidate</em> options. MCP tool calls include caching
|
||||
information in their <em>_meta</em> fields, providing parity with
|
||||
standard HTTP headers. All caching takes place in Cloudflare's global
|
||||
edge cache, and caching will only be enabled if you choose to enable it
|
||||
for your product or individual tools.
|
||||
</>
|
||||
),
|
||||
icon: DatabaseZapIcon,
|
||||
pattern: {
|
||||
y: 8,
|
||||
squares: [
|
||||
[0, 2],
|
||||
[-1, 1]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Analytics',
|
||||
description: (
|
||||
<>
|
||||
Agentic tracks all tool calls for usage-based billing and analytics at a
|
||||
fine-grained level, so you can drill in and deeply understand how your
|
||||
customers are using your product.
|
||||
</>
|
||||
),
|
||||
icon: ChartNoAxesCombinedIcon,
|
||||
pattern: {
|
||||
y: -2,
|
||||
squares: [[-2, 2]]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Versioning',
|
||||
description: (
|
||||
<>
|
||||
Just like Vercel, Agentic uses immutable deployments, so every time you
|
||||
make a change to your product's config, pricing, or docs, a unique
|
||||
preview deployment is created for that change. This enables instant
|
||||
rollbacks if there are problems with a deployment. Publishing
|
||||
deployments publicly uses semantic versioning (<em>semver</em>), so your
|
||||
customers can choose how to handle breaking changes.
|
||||
</>
|
||||
),
|
||||
icon: HistoryIcon,
|
||||
pattern: {
|
||||
y: 26,
|
||||
squares: [
|
||||
[2, 4],
|
||||
[-2, 3]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "That's just the start",
|
||||
description: (
|
||||
<>Check out our docs for more details on Agentic's MCP gateway.</>
|
||||
),
|
||||
href: docsUrl,
|
||||
icon: TextSelectIcon,
|
||||
pattern: {
|
||||
y: 13,
|
||||
squares: [
|
||||
[0, 2],
|
||||
[0, 2]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
function Feature({ name, description, icon, pattern, href }: Feature) {
|
||||
const mouseX = useMotionValue(0)
|
||||
const mouseY = useMotionValue(0)
|
||||
|
||||
function onMouseMove({
|
||||
currentTarget,
|
||||
clientX,
|
||||
clientY
|
||||
}: React.MouseEvent<HTMLElement>) {
|
||||
const { left, top } = currentTarget.getBoundingClientRect()
|
||||
mouseX.set(clientX - left)
|
||||
mouseY.set(clientY - top)
|
||||
}
|
||||
|
||||
const content = (
|
||||
<>
|
||||
<FeaturePattern {...pattern} mouseX={mouseX} mouseY={mouseY} />
|
||||
|
||||
<div className='ring-gray-900/7.5 group-hover:ring-gray-900/10 absolute inset-0 rounded-2xl ring-1 ring-inset dark:ring-white/10 dark:group-hover:ring-white/20' />
|
||||
|
||||
<div className='relative rounded-2xl px-4 pb-4 pt-16'>
|
||||
<FeatureIcon icon={icon} />
|
||||
|
||||
<h3 className='text-gray-900 mt-4 text-[0.875rem] font-semibold leading-7 dark:text-white'>
|
||||
{/* <span className='absolute inset-0 rounded-2xl' /> */}
|
||||
{name}
|
||||
</h3>
|
||||
|
||||
<p className='text-gray-600 dark:text-gray-400 mt-1 text-[0.875rem] leading-[1.5rem]'>
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
const className =
|
||||
'dark:bg-white/2.5 bg-gray-50 hover:shadow-gray-900/5 group relative flex rounded-2xl transition-shadow hover:shadow-md dark:hover:shadow-black/5'
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
key={name}
|
||||
onMouseMove={onMouseMove}
|
||||
className={className}
|
||||
>
|
||||
{content}
|
||||
</Link>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<div key={name} onMouseMove={onMouseMove} className={className}>
|
||||
{content}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
function FeatureIcon({ icon: Icon }: { icon: Feature['icon'] }) {
|
||||
return (
|
||||
<div className='dark:bg-white/7.5 bg-gray-900/5 ring-gray-900/25 group-hover:ring-gray-900/25 dark:group-hover:bg-sky-300/10 dark:group-hover:ring-sky-400 flex size-7 items-center justify-center rounded-full ring-1 backdrop-blur-[2px] transition duration-300 group-hover:bg-white/50 dark:ring-white/15'>
|
||||
<Icon className='fill-gray-700/10 stroke-gray-700 group-hover:stroke-gray-900 dark:stroke-gray-400 dark:group-hover:stroke-sky-400 dark:group-hover:fill-sky-300/10 size-5 transition-colors duration-300 dark:fill-white/10' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function FeaturePattern({
|
||||
mouseX,
|
||||
mouseY,
|
||||
...gridProps
|
||||
}: Feature['pattern'] & {
|
||||
mouseX: MotionValue<number>
|
||||
mouseY: MotionValue<number>
|
||||
}) {
|
||||
const maskImage = useMotionTemplate`radial-gradient(180px at ${mouseX}px ${mouseY}px, white, transparent)`
|
||||
const style = { maskImage, WebkitMaskImage: maskImage }
|
||||
|
||||
return (
|
||||
<div className='pointer-events-none'>
|
||||
<div className='absolute inset-0 rounded-2xl transition duration-300 [mask-image:linear-gradient(white,transparent)] group-hover:opacity-50'>
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x='50%'
|
||||
className='dark:fill-white/1 dark:stroke-white/2.5 absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/[0.02] stroke-black/5'
|
||||
{...gridProps}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
className='from-sky-100 to-sky-300 dark:from-sky-500 dark:to-sky-300 absolute inset-0 rounded-2xl bg-gradient-to-r opacity-0 transition duration-300 group-hover:opacity-50 dark:group-hover:opacity-15'
|
||||
style={style}
|
||||
/>
|
||||
|
||||
<motion.div
|
||||
className='absolute inset-0 rounded-2xl opacity-0 mix-blend-overlay transition duration-300 group-hover:opacity-100'
|
||||
style={style}
|
||||
>
|
||||
<GridPattern
|
||||
width={72}
|
||||
height={56}
|
||||
x='50%'
|
||||
className='dark:fill-white/2.5 absolute inset-x-0 inset-y-[-30%] h-[160%] w-full skew-y-[-18deg] fill-black/50 stroke-black/70 dark:stroke-white/10'
|
||||
{...gridProps}
|
||||
/>
|
||||
</motion.div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function Features() {
|
||||
return (
|
||||
<div className='xl:max-w-none'>
|
||||
<div className='not-prose grid grid-cols-1 gap-8 sm:grid-cols-2 xl:grid-cols-3'>
|
||||
{FEATURES.map((feature) => (
|
||||
<Feature key={feature.name} {...feature} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -3,7 +3,7 @@ import Link from 'next/link'
|
|||
import { ActiveLink } from '@/components/active-link'
|
||||
import { GitHubIcon } from '@/icons/github'
|
||||
import { TwitterIcon } from '@/icons/twitter'
|
||||
import { copyright, githubUrl, twitterUrl } from '@/lib/config'
|
||||
import { copyright, docsUrl, githubUrl, twitterUrl } from '@/lib/config'
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
|
@ -21,12 +21,24 @@ export function Footer() {
|
|||
</ActiveLink>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<ActiveLink href='/marketplace' className='link'>
|
||||
MCP Marketplace
|
||||
</ActiveLink>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<ActiveLink href='/mcp-authors' className='link'>
|
||||
For MCP Authors
|
||||
</ActiveLink>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<ActiveLink href={docsUrl} className='link'>
|
||||
Docs
|
||||
</ActiveLink>
|
||||
</span>
|
||||
|
||||
<span>
|
||||
<ActiveLink href='/about' className='link'>
|
||||
About
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
import { type SVGProps, useId } from 'react'
|
||||
|
||||
export type GridPattern = Omit<
|
||||
SVGProps<SVGSVGElement>,
|
||||
'width' | 'height' | 'x' | 'y'
|
||||
> & {
|
||||
width: number
|
||||
height: number
|
||||
x: string | number
|
||||
y: string | number
|
||||
squares: Array<[x: number, y: number]>
|
||||
}
|
||||
|
||||
export function GridPattern({
|
||||
width,
|
||||
height,
|
||||
x,
|
||||
y,
|
||||
squares,
|
||||
...props
|
||||
}: GridPattern) {
|
||||
const patternId = useId()
|
||||
|
||||
return (
|
||||
<svg aria-hidden='true' {...props}>
|
||||
<defs>
|
||||
<pattern
|
||||
id={patternId}
|
||||
width={width}
|
||||
height={height}
|
||||
patternUnits='userSpaceOnUse'
|
||||
x={x}
|
||||
y={y}
|
||||
>
|
||||
<path d={`M.5 ${height}V.5H${width}`} fill='none' />
|
||||
</pattern>
|
||||
</defs>
|
||||
|
||||
<rect
|
||||
width='100%'
|
||||
height='100%'
|
||||
strokeWidth={0}
|
||||
fill={`url(#${patternId})`}
|
||||
/>
|
||||
|
||||
{squares && (
|
||||
<svg x={x} y={y} className='overflow-visible'>
|
||||
<title>square</title>
|
||||
|
||||
{squares.map(([x, y]) => (
|
||||
<rect
|
||||
strokeWidth='0'
|
||||
key={`${x}-${y}`}
|
||||
width={width + 1}
|
||||
height={height + 1}
|
||||
x={x * width}
|
||||
y={y * height}
|
||||
/>
|
||||
))}
|
||||
</svg>
|
||||
)}
|
||||
</svg>
|
||||
)
|
||||
}
|
|
@ -19,7 +19,7 @@ export function Header() {
|
|||
|
||||
<div className='flex justify-end items-center h-full gap-4'>
|
||||
<ActiveLink href='/marketplace' className='link'>
|
||||
Marketplace
|
||||
MCP Marketplace
|
||||
</ActiveLink>
|
||||
|
||||
<ActiveLink href={docsUrl} className='link'>
|
||||
|
|
|
@ -19,7 +19,7 @@ export function SupplySideCTA({
|
|||
const ctx = useAgentic()
|
||||
|
||||
return (
|
||||
<div className='flex justify-center items-center gap-8'>
|
||||
<div className='flex justify-center items-center gap-12'>
|
||||
<HeroButton asChild className=''>
|
||||
<Link
|
||||
href={
|
||||
|
|
Ładowanie…
Reference in New Issue