kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: website improvements
rodzic
2d51267943
commit
8f752139b4
|
@ -1,19 +1,20 @@
|
||||||
import { HeroButton } from '@/components/hero-button'
|
import { SupplySideCTA } from '@/components/supply-side-cta'
|
||||||
|
|
||||||
export default function IndexPage() {
|
export default function IndexPage() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<section>
|
<section className='gap-8'>
|
||||||
<h1 className='my-0! text-center text-balance leading-snug md:leading-none text-4xl font-extrabold'>
|
<h1 className='my-0! text-center text-balance leading-snug md:leading-none text-4xl font-extrabold'>
|
||||||
MCP tools that actually work
|
Your API → Paid MCP, Instantly
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<h5 className='my-8! text-center text-balance text-lg'>
|
<h5 className='text-center text-lg max-w-2xl'>
|
||||||
Deploy any MCP server or OpenAPI service to Agentic's MCP gateway, and
|
Run one command to turn any MCP server or OpenAPI service into a paid
|
||||||
in minutes have a production-ready, monetizable MCP product.
|
MCP product,{' '}
|
||||||
|
<em>with built-in distribution to over 20k AI engineers</em>.
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<HeroButton>Get Started</HeroButton>
|
<SupplySideCTA />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className='flex-1'>
|
<section className='flex-1'>
|
||||||
|
|
|
@ -37,9 +37,14 @@ export const ActiveLink = React.forwardRef(function ActiveLink(
|
||||||
const [disabled, setDisabled] = React.useState(false)
|
const [disabled, setDisabled] = React.useState(false)
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const linkPathname = new URL(href as string, location.href).pathname
|
const currentUrl = new URL(location.href)
|
||||||
|
const url = new URL(href as string, currentUrl)
|
||||||
|
const linkPathname = url.pathname
|
||||||
|
const linkOrigin = url.origin
|
||||||
|
|
||||||
setDisabled(compare(linkPathname, pathname))
|
setDisabled(
|
||||||
|
compare(linkPathname, pathname) && compare(linkOrigin, currentUrl.origin)
|
||||||
|
)
|
||||||
}, [pathname, href, compare])
|
}, [pathname, href, compare])
|
||||||
|
|
||||||
const styleOverride = React.useMemo<React.CSSProperties>(
|
const styleOverride = React.useMemo<React.CSSProperties>(
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
import { HeroButton } from '@/components/hero-button'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { docsMarketplaceUrl } from '@/lib/config'
|
||||||
|
|
||||||
|
export function DemandSideCTA() {
|
||||||
|
return (
|
||||||
|
<div className='flex justify-center items-center gap-8'>
|
||||||
|
<HeroButton asChild className='h-full'>
|
||||||
|
<Link href='/marketplace'>MCP Marketplace</Link>
|
||||||
|
</HeroButton>
|
||||||
|
|
||||||
|
<Button variant='outline' asChild className='h-full'>
|
||||||
|
<Link href={docsMarketplaceUrl}>Check out the marketplace docs</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -3,6 +3,7 @@
|
||||||
import { ActiveLink } from '@/components/active-link'
|
import { ActiveLink } from '@/components/active-link'
|
||||||
import { useAgentic } from '@/components/agentic-provider'
|
import { useAgentic } from '@/components/agentic-provider'
|
||||||
import { DarkModeToggle } from '@/components/dark-mode-toggle'
|
import { DarkModeToggle } from '@/components/dark-mode-toggle'
|
||||||
|
import { docsUrl } from '@/lib/config'
|
||||||
|
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
|
|
||||||
|
@ -21,6 +22,10 @@ export function Header() {
|
||||||
Marketplace
|
Marketplace
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
|
|
||||||
|
<ActiveLink href={docsUrl} className='link'>
|
||||||
|
Docs
|
||||||
|
</ActiveLink>
|
||||||
|
|
||||||
<ActiveLink href='/about' className='link'>
|
<ActiveLink href='/about' className='link'>
|
||||||
About
|
About
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
|
|
|
@ -1,56 +1,46 @@
|
||||||
import type * as React from 'react'
|
import type * as React from 'react'
|
||||||
|
import type { Simplify } from 'type-fest'
|
||||||
import cs from 'clsx'
|
import cs from 'clsx'
|
||||||
import Link from 'next/link'
|
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button, type ButtonProps } from '@/components/ui/button'
|
||||||
|
|
||||||
import styles from './styles.module.css'
|
import styles from './styles.module.css'
|
||||||
|
|
||||||
export type HeroButtonVariant = 'orange' | 'blue' | 'purple'
|
export type HeroButtonVariant = 'orange' | 'blue' | 'purple'
|
||||||
|
|
||||||
|
export type HeroButtonProps = Simplify<
|
||||||
|
{
|
||||||
|
heroVariant?: HeroButtonVariant
|
||||||
|
className?: string
|
||||||
|
buttonClassName?: string
|
||||||
|
} & ButtonProps
|
||||||
|
>
|
||||||
|
|
||||||
export function HeroButton({
|
export function HeroButton({
|
||||||
variant = 'purple',
|
heroVariant = 'purple',
|
||||||
className,
|
className,
|
||||||
buttonClassName,
|
buttonClassName,
|
||||||
children,
|
|
||||||
...buttonProps
|
...buttonProps
|
||||||
}: {
|
}: HeroButtonProps) {
|
||||||
variant?: HeroButtonVariant
|
|
||||||
className?: string
|
|
||||||
buttonClassName?: string
|
|
||||||
children: React.ReactNode
|
|
||||||
} & React.AnchorHTMLAttributes<HTMLAnchorElement>) {
|
|
||||||
return (
|
return (
|
||||||
<div className={cs(styles.heroButtonWrapper, className)}>
|
<div className={cs(styles.heroButtonWrapper, className)}>
|
||||||
{variant === 'blue' && (
|
{heroVariant === 'blue' && (
|
||||||
<span className={cs(styles.heroButtonBg, styles.heroButtonBg1)} />
|
<span className={cs(styles.heroButtonBg, styles.heroButtonBg1)} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{variant === 'purple' && (
|
{heroVariant === 'purple' && (
|
||||||
<span className={cs(styles.heroButtonBg, styles.heroButtonBg2)} />
|
<span className={cs(styles.heroButtonBg, styles.heroButtonBg2)} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{variant === 'orange' && (
|
{heroVariant === 'orange' && (
|
||||||
<span className={cs(styles.heroButtonBg, styles.heroButtonBg3)} />
|
<span className={cs(styles.heroButtonBg, styles.heroButtonBg3)} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{buttonProps.href ? (
|
<Button
|
||||||
<Link
|
className={cs(styles.heroButton, buttonClassName)}
|
||||||
className={cs(styles.heroButton, buttonClassName)}
|
type='button'
|
||||||
href={buttonProps.href}
|
{...(buttonProps as any)}
|
||||||
{...buttonProps}
|
/>
|
||||||
>
|
|
||||||
<div className={styles.heroButtonContent}>{children}</div>
|
|
||||||
</Link>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
className={cs(styles.heroButton, buttonClassName)}
|
|
||||||
{...(buttonProps as any)}
|
|
||||||
type='button'
|
|
||||||
>
|
|
||||||
<div className={styles.heroButtonContent}>{children}</div>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
.heroButtonWrapper {
|
.heroButtonWrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 100;
|
max-width: 100%;
|
||||||
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroButtonBg1 {
|
.heroButtonBg1 {
|
||||||
|
@ -53,7 +54,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroButton {
|
.heroButton {
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
|
@ -64,17 +64,15 @@
|
||||||
transition-property: color, background-color, box-shadow;
|
transition-property: color, background-color, box-shadow;
|
||||||
transition-duration: 0.15s;
|
transition-duration: 0.15s;
|
||||||
transition-timing-function: ease;
|
transition-timing-function: ease;
|
||||||
padding: 12px 24px;
|
padding: 20px 24px;
|
||||||
line-height: 1.5em;
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
font-weight: 400;
|
|
||||||
font-size: 1rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
--lighten-color: hsla(0, 0%, 100%, 0.8);
|
--lighten-color: hsla(0, 0%, 100%, 0.8);
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
|
@ -88,13 +86,6 @@
|
||||||
--lighten-color: rgba(0, 0, 0, 0.75);
|
--lighten-color: rgba(0, 0, 0, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
.heroButtonContent {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.heroButton:hover {
|
.heroButton:hover {
|
||||||
--lighten-color: transparent;
|
--lighten-color: transparent;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import Link from 'next/link'
|
||||||
|
|
||||||
|
import { HeroButton } from '@/components/hero-button'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import { calendarBookingUrl, docsQuickStartUrl } from '@/lib/config'
|
||||||
|
|
||||||
|
export function SupplySideCTA() {
|
||||||
|
return (
|
||||||
|
<div className='flex justify-center items-center gap-8'>
|
||||||
|
<HeroButton asChild className='h-full'>
|
||||||
|
<Link href={docsQuickStartUrl}>Get Started</Link>
|
||||||
|
</HeroButton>
|
||||||
|
|
||||||
|
<Button variant='outline' asChild className='h-full'>
|
||||||
|
<Link href={calendarBookingUrl} target='_blank' rel='noopener'>
|
||||||
|
Book a call with me 👋
|
||||||
|
</Link>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
|
@ -15,6 +15,13 @@ export const twitterUrl = `https://x.com/${authorTwitterUsername}`
|
||||||
export const copyright = `© ${new Date().getFullYear()} Agentic. All rights reserved.`
|
export const copyright = `© ${new Date().getFullYear()} Agentic. All rights reserved.`
|
||||||
export const githubUrl = 'https://github.com/transitive-bullshit/agentic'
|
export const githubUrl = 'https://github.com/transitive-bullshit/agentic'
|
||||||
|
|
||||||
|
// TODO: make an agentic-specific calendar for this
|
||||||
|
export const calendarBookingUrl =
|
||||||
|
'https://cal.com/travis-fischer/15min?overlayCalendar=true'
|
||||||
|
export const docsUrl = 'https://docs.agentic.so'
|
||||||
|
export const docsQuickStartUrl = `${docsUrl}/quick-start`
|
||||||
|
export const docsMarketplaceUrl = `${docsUrl}/marketplace`
|
||||||
|
|
||||||
export const keywords = [
|
export const keywords = [
|
||||||
'agentic',
|
'agentic',
|
||||||
'MCP',
|
'MCP',
|
||||||
|
|
Ładowanie…
Reference in New Issue