Skip to content

Commit 4dde9f4

Browse files
committed
wip
1 parent 43b6f1b commit 4dde9f4

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed

src/components/index-page/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { QuotesFromTheIndustry } from "./quotes-from-the-industry"
1111
import { JoinTheCommunity } from "./join-the-community"
1212
import { DataColocation } from "./data-colocation"
1313
import { WhatIsGraphQL } from "./what-is-graphql"
14+
import { UseCases } from "./use-cases"
1415

1516
export function IndexPage() {
1617
return (
@@ -30,6 +31,7 @@ export function IndexPage() {
3031
<PoweredByCommunity />
3132
<GraphQLAdvantages />
3233
<DataColocation />
34+
<UseCases />
3335
<QuotesFromTheIndustry />
3436
<JoinTheCommunity />
3537
</div>
Lines changed: 3 additions & 0 deletions
Loading
Binary file not shown.
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
"use client"
2+
3+
import clsx from "clsx"
4+
import { useState } from "react"
5+
6+
import { Button } from "@/app/conf/_design-system/button"
7+
import ArrowRightIcon from "./arrow-right.svg?svgr"
8+
9+
type UseCase = {
10+
label: string
11+
description: string
12+
cta: string
13+
href: string
14+
}
15+
16+
const USE_CASES: UseCase[] = [
17+
{
18+
label: "A large backend with many services",
19+
description:
20+
"GraphQL serves as a unified data layer across multiple services. You simplify API management, reduce cross-team dependencies, and keep the API surface flexible and maintainable.",
21+
cta: "Best Practices for Large-Scale Systems",
22+
href: "/learn/best-practices",
23+
},
24+
{
25+
label: "A mobile app",
26+
description:
27+
"Fetch only the data you need to minimize payload size and round-trips. Build resilient UIs that work well on variable networks.",
28+
cta: "Mobile Patterns",
29+
href: "/learn/best-practices#mobile",
30+
},
31+
{
32+
label: "A frontend-heavy app with advanced UI needs",
33+
description:
34+
"Co-locate queries with components and keep state consistent. Compose data from many backends without bespoke endpoints.",
35+
cta: "Frontend Integration Guide",
36+
href: "/learn/queries#components",
37+
},
38+
{
39+
label: "An app with real-time updates",
40+
description:
41+
"Use subscriptions for low-latency updates while keeping the schema as the single contract for clients and servers.",
42+
cta: "Real-time with Subscriptions",
43+
href: "/learn/subscriptions",
44+
},
45+
{
46+
label: "A simple full stack TypeScript app",
47+
description:
48+
"Strong types end-to-end with code generation and great DX. Ship faster without compromising correctness.",
49+
cta: "Full Stack TS Starter",
50+
href: "/learn#typescript",
51+
},
52+
]
53+
54+
export function UseCases({
55+
className,
56+
...props
57+
}: React.HTMLAttributes<HTMLElement>) {
58+
const [selectedIndex, setSelectedIndex] = useState(0)
59+
const selected = USE_CASES[selectedIndex]
60+
61+
return (
62+
<section
63+
className={clsx("gql-section gql-container dark:text-neu-0", className)}
64+
{...props}
65+
>
66+
<div className="flex *:basis-1/2 max-lg:flex-col">
67+
<div className="border-sec-dark bg-sec-light p-4 lg:border-r lg:p-8 xl:p-16">
68+
<h2 className="typography-h2">Is GraphQL right for&nbsp;me?</h2>
69+
<p className="typography-body-lg mt-6 text-neu-800">
70+
Choose a use case most relevant for your project and learn how
71+
GraphQL can help you build faster, modern solutions.
72+
</p>
73+
74+
<ul className="mt-8 divide-y divide-sec-dark border border-sec-dark">
75+
{USE_CASES.map((useCase, i) => (
76+
<li key={useCase.label}>
77+
<button
78+
type="button"
79+
onClick={() => setSelectedIndex(i)}
80+
aria-selected={i === selectedIndex ? "true" : undefined}
81+
className="flex w-full items-center justify-between gap-6 px-3 py-4 text-left transition-colors hover:bg-sec-lighter aria-selected:bg-sec-base aria-selected:hover:bg-sec-lighter"
82+
>
83+
<span className="typography-body-lg">{useCase.label}</span>
84+
<ArrowRightIcon className="size-5 shrink-0 text-sec-dark" />
85+
</button>
86+
</li>
87+
))}
88+
</ul>
89+
</div>
90+
91+
<article className="relative flex h-auto flex-col bg-pri-light p-8 md:p-12 lg:p-16">
92+
<Stripes />
93+
<div className="z-10 max-w-2xl">
94+
<h3 className="typography-h3 text-neu-900">{selected.label}</h3>
95+
<p className="typography-body-lg mt-6 text-neu-700">
96+
{selected.description}
97+
</p>
98+
<div className="mt-8">
99+
<Button href={selected.href} variant="primary">
100+
{selected.cta}
101+
</Button>
102+
</div>
103+
</div>
104+
</article>
105+
</div>
106+
</section>
107+
)
108+
}
109+
110+
const maskEven =
111+
"repeating-linear-gradient(to right, transparent, transparent 12px, black 12px, black 24px)"
112+
const maskOdd =
113+
"repeating-linear-gradient(to right, black, black 12px, transparent 12px, transparent 24px)"
114+
115+
function Stripes() {
116+
const mask = "linear-gradient(125deg, transparent 68%, hsl(0 0 0 / 0.8))"
117+
return (
118+
<div
119+
role="presentation"
120+
className="pointer-events-none absolute inset-0 bottom-[-20px] -z-10 translate-x-0.5 translate-y-12 ease-linear max-lg:hidden"
121+
style={{
122+
maskImage: mask,
123+
WebkitMaskImage: mask,
124+
}}
125+
>
126+
<div
127+
className="absolute inset-0"
128+
style={{
129+
maskImage: maskOdd,
130+
WebkitMaskImage: maskOdd,
131+
maskPosition: "right",
132+
backgroundImage:
133+
"linear-gradient(0deg, hsl(var(--color-sec-lighter)) 0%, rgba(133, 185, 19, 0.00) 100%)",
134+
}}
135+
/>
136+
<div
137+
className="absolute inset-0"
138+
style={{
139+
maskImage: maskEven,
140+
WebkitMaskImage: maskEven,
141+
maskPosition: "right",
142+
backgroundImage:
143+
"linear-gradient(0deg, hsl(var(--color-sec-dark)) 0%, hsl(var(--color-sec-base)) 100%)",
144+
}}
145+
/>
146+
</div>
147+
)
148+
}

0 commit comments

Comments
 (0)