import { IconArrowRight as ArrowRightIcon } from '@tabler/icons-react'; import type { ReactNode } from 'react'; import { useDocsVisibility } from '@/hooks/api'; import { isDocsHrefVisible } from '@/lib/docs-links'; import { cn } from '@/lib/utils'; import { ShimmerBadge } from '../ShimmerBadge'; import Glow from '../ui/glow'; import { LinkButton, type LinkButtonProps } from '../ui/link-button'; import { Mockup, MockupFrame } from '../ui/mockup'; import { Section } from '../ui/section'; /* * Marketing hero. Adapted from Launch UI (MIT) for Vite: lucide -> Tabler, * next/* removed, and the content genericized as a starting point for the * generated app. Replace the copy and the mockup with your own. */ interface HeroButtonProps extends Omit { text: string; } interface HeroProps { title?: string; description?: string; mockup?: ReactNode | false; badge?: ReactNode | false; buttons?: HeroButtonProps[] | false; className?: string; } const DEFAULT_HERO_BUTTONS: HeroButtonProps[] = [ { href: '/signup', text: 'Get started', variant: 'default' }, { href: '/docs', text: 'View docs', variant: 'glow' }, ]; // The marketing eyebrow reuses the landing hero's ShimmerBadge (same component). const DEFAULT_HERO_BADGE = ( React · Supabase · Stripe ); // Neutral placeholder — swap for a of your own app. const DEFAULT_HERO_MOCKUP = (
Your app preview
); export default function Hero({ title = 'Your first commit is a feature.', description = 'Authentication, billing, and an admin dashboard, wired together and working on the first run. Everything after that is your product.', mockup = DEFAULT_HERO_MOCKUP, badge = DEFAULT_HERO_BADGE, buttons = DEFAULT_HERO_BUTTONS, className, }: HeroProps) { const docsVisibility = useDocsVisibility(); // The default "View docs" CTA disappears with user docs turned off; the // primary "Get started" button carries the section on its own. const visibleButtons = buttons === false ? false : buttons.filter((b) => isDocsHrefVisible(b.href, docsVisibility)); return (
{badge !== false && badge}

{title}

{description}

{visibleButtons !== false && visibleButtons.length > 0 && (
{visibleButtons.map((button) => ( } > {button.text} ))}
)} {mockup !== false && (
{mockup}
)}
); }