Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions website/src/components/hero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { cn } from '@theguild/components';

// TODO: Move these to `@theguild/components` and remove from here, Codegen and Hive.

export interface HeroContainerProps extends React.HTMLAttributes<HTMLDivElement> {}
export function HeroContainer(props: HeroContainerProps) {
return (
<div
{...props}
className={cn(
'relative isolate flex max-w-[90rem] flex-col items-center justify-center gap-6 overflow-hidden rounded-3xl bg-blue-400 px-4 py-6 sm:py-12 md:gap-8 lg:py-24',
props.className,
)}
/>
);
}

export interface HeroLinksProps extends React.HTMLAttributes<HTMLDivElement> {}
export function HeroLinks(props: HeroLinksProps) {
return (
<div
{...props}
className={cn(
'relative z-10 flex justify-center gap-2 px-0.5 max-sm:flex-col sm:gap-4',
props.className,
)}
/>
);
}

export interface HeroFeaturesProps extends React.HTMLAttributes<HTMLUListElement> {}
export function HeroFeatures(props: HeroFeaturesProps) {
return (
<ul
{...props}
className={cn(
'mx-auto flex list-none gap-x-6 gap-y-2 text-sm font-medium max-md:flex-col [&>li]:flex [&>li]:items-center [&>li]:gap-2',
props.className,
)}
/>
);
}
40 changes: 3 additions & 37 deletions website/src/components/index-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import meshDiagram from '@/public/assets/mesh-diagram.svg';
import meshExampleLogo from '@/public/assets/mesh-example.png';
import openSourceLogo from '@/public/assets/open-source.svg';
import { Anchor } from '@theguild/components';
import { MeshHero } from './mesh-hero';

const ButtonLink = ({ children, ...props }: React.ComponentProps<typeof Anchor>) => {
return (
Expand All @@ -20,40 +21,6 @@ const ButtonLink = ({ children, ...props }: React.ComponentProps<typeof Anchor>)
);
};

function Hero() {
return (
<div className="w-full">
<div className="py-20 sm:py-24 lg:py-32 my-6">
<h1 className="max-w-screen-md mx-auto font-extrabold text-5xl sm:text-5xl lg:text-6xl text-center bg-gradient-to-r from-cyan-400 to-sky-500 dark:from-cyan-400 dark:to-sky-600 bg-clip-text text-transparent">
GraphQL Mesh
</h1>
<p className="max-w-screen-sm mx-auto mt-6 text-2xl text-gray-600 text-center dark:text-gray-400">
The Graph of Everything
</p>
<p className="max-w-screen-sm mx-auto text-2xl text-gray-600 text-center dark:text-gray-400">
Federated architecture for any API service
</p>
<div className="mt-10 flex flex-col sm:flex-row items-center justify-center gap-4">
<ButtonLink href="/v1">Documentation</ButtonLink>
{/* <ButtonLink className="hidden lg:block" href="/examples">
Examples
</ButtonLink> */}
<ButtonLink
className="flex flex-row gap-2 items-center"
href="https://github.com/ardatan/graphql-mesh"
>
<FiGithub /> GitHub
</ButtonLink>
{/* TODO: this button causes hydration error */}
{/* <ButtonLink href="https://www.npmjs.com/package/@graphql-mesh/cli">
<NPMBadge name="@graphql-mesh/cli" />
</ButtonLink> */}
</div>
</div>
</div>
);
}

const FeatureWrapperClass = `
w-full py-24
odd:bg-gray-50
Expand Down Expand Up @@ -206,9 +173,8 @@ const datasources: Array<string> = [
export function IndexPage(): ReactElement {
return (
<div className="flex flex-col">
<div className={FeatureWrapperClass}>
<Hero />
</div>
<MeshHero className="mx-4 max-sm:mt-2 md:mx-6" />

<Feature
title="Query anything, run anywhere."
description={
Expand Down
39 changes: 39 additions & 0 deletions website/src/components/install-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use client';

import { useState } from 'react';
import { CallToAction, CheckIcon } from '@theguild/components';

// TODO: We'll add more package managers later.
export function InstallButton() {
const text = 'npm i graphql-mesh';

const [copied, setCopied] = useState(false);

return (
<CallToAction
variant="secondary-inverted"
className="font-mono font-medium"
onClick={() => {
navigator.clipboard.writeText(text);
setCopied(true);
setTimeout(() => {
setCopied(false);
}, 2000);
}}
>
{text}
{copied ? <CheckIcon className="size-6" /> : <CopyIcon className="size-6" />}
</CallToAction>
);
}

function CopyIcon(props: React.SVGProps<SVGSVGElement>) {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="24" viewBox="0 0 25 24" {...props}>
<path
d="M7.9999 6.6V3.9C7.9999 3.66131 8.09472 3.43239 8.26351 3.2636C8.43229 3.09482 8.66121 3 8.8999 3H19.6999C19.9386 3 20.1675 3.09482 20.3363 3.2636C20.5051 3.43239 20.5999 3.66131 20.5999 3.9V16.5C20.5999 16.7387 20.5051 16.9676 20.3363 17.1364C20.1675 17.3052 19.9386 17.4 19.6999 17.4H16.9999V20.1C16.9999 20.5968 16.5949 21 16.0936 21H5.3062C5.18752 21.0007 5.06986 20.978 4.95999 20.9331C4.85012 20.8882 4.75021 20.822 4.666 20.7384C4.58178 20.6547 4.51492 20.5553 4.46925 20.4457C4.42359 20.3362 4.40002 20.2187 4.3999 20.1L4.4026 7.5C4.4026 7.0032 4.8076 6.6 5.3089 6.6H7.9999ZM6.2026 8.4L6.1999 19.2H15.1999V8.4H6.2026ZM9.7999 6.6H16.9999V15.6H18.7999V4.8H9.7999V6.6Z"
fill="currentColor"
/>
</svg>
);
}
89 changes: 89 additions & 0 deletions website/src/components/mesh-hero-badge.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions website/src/components/mesh-hero.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Image from 'next/image';
import {
CallToAction,
CheckIcon,
cn,
DecorationIsolation,
GitHubIcon,
Heading,
MeshIcon,
} from '@theguild/components';
import { HeroContainer, HeroContainerProps, HeroFeatures, HeroLinks } from './hero';
import { InstallButton } from './install-button';
import meshHeroBadge from './mesh-hero-badge.svg';

export function MeshHero(props: HeroContainerProps) {
return (
<HeroContainer {...props} className={cn('mx-4 max-sm:mt-2 md:mx-6', props.className)}>
<MeshDecorations />
<Image priority src={meshHeroBadge} alt="" width="96" height="96" />
<Heading as="h1" size="xl" className="mx-auto max-w-3xl text-balance text-center">
GraphQL Mesh
</Heading>
<p className="mx-auto w-[512px] max-w-[80%] text-balance text-center leading-6 text-green-800">
Unify your API landscape with Mesh’s federated architecture, integrating any API service
into a cohesive graph.
</p>
<HeroFeatures>
<li>
<CheckIcon className="text-green-800" />
Compose any API
</li>
<li>
<CheckIcon className="text-green-800" />
Granular field access
</li>
<li>
<CheckIcon className="text-green-800" />
Works with any schema registry
</li>
</HeroFeatures>
<HeroLinks>
<CallToAction variant="primary-inverted" href="/v1/getting-started">
Get started
</CallToAction>
<InstallButton />
<CallToAction
variant="tertiary"
href="https://github.com/dotansimha/graphql-code-generator"
>
<GitHubIcon className="size-6" />
GitHub
</CallToAction>
</HeroLinks>
</HeroContainer>
);
}

function MeshDecorations() {
return (
<DecorationIsolation className="-z-10">
<MeshIcon className="absolute left-[-200px] top-[calc(50%-200px)] size-[400px] [&>g]:fill-[url(#mesh-hero-gradient)] [&>g]:stroke-white/10 [&>g]:stroke-[0.1px]" />
<MeshIcon className="absolute size-[640px] bottom-[-327px] right-[-316px] [&>g]:fill-[url(#mesh-hero-gradient)] [&>g]:stroke-white/10 [&>g]:stroke-[0.1px] max-md:hidden" />
<svg>
<defs>
<linearGradient id="mesh-hero-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="11.66%" stopColor="rgba(255, 255, 255, 0.10)" />
<stop offset="74.87%" stopColor="rgba(255, 255, 255, 0.30)" />
</linearGradient>
</defs>
</svg>
</DecorationIsolation>
);
}
Loading