Skip to content

Commit 8924c22

Browse files
authored
feat: DR-7749 client page (#7703)
* Add first step of client page * Update first section of client * Add client page * Add spaces to icons * Update spacings * Update select trigger for all instances * remove classname from select component * Update links for client page * ammend conflict merge * Further update theme switching
1 parent ea2ff40 commit 8924c22

13 files changed

Lines changed: 1282 additions & 56 deletions

File tree

apps/site/public/illustrations/client/client_0.svg

Lines changed: 101 additions & 0 deletions
Loading

apps/site/public/illustrations/client/client_0_light.svg

Lines changed: 101 additions & 0 deletions
Loading

apps/site/public/illustrations/client/client_1.svg

Lines changed: 65 additions & 0 deletions
Loading

apps/site/public/illustrations/client/client_1_light.svg

Lines changed: 38 additions & 0 deletions
Loading

apps/site/src/app/client/page.tsx

Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
import type { Metadata } from "next";
2+
import {
3+
SITE_HOME_DESCRIPTION,
4+
SITE_HOME_TITLE,
5+
} from "../../lib/blog-metadata";
6+
import { Action, Button, Card } from "@prisma/eclipse";
7+
import API from "@/components/client/api";
8+
import { CardSection } from "@/components/homepage/card-section/card-section";
9+
import { cn } from "@/lib/cn";
10+
import { Technology } from "@/components/client/technology";
11+
12+
export const metadata: Metadata = {
13+
title: SITE_HOME_TITLE,
14+
description: SITE_HOME_DESCRIPTION,
15+
};
16+
17+
const databases = {
18+
title: "Supported Databases",
19+
list: [
20+
{
21+
name: "PostgreSQL",
22+
icon: "/icons/companies/postgres.svg",
23+
url: "/",
24+
},
25+
{
26+
name: "MySQL",
27+
icon: "/icons/technologies/mysqlsimple.svg",
28+
url: "/",
29+
},
30+
{
31+
name: "MariaDB",
32+
icon: "/icons/technologies/mariadb.svg",
33+
url: "/",
34+
},
35+
{
36+
name: "SQLite",
37+
icon: "/icons/companies/sqlite.svg",
38+
url: "/",
39+
},
40+
{
41+
name: "SQL Server",
42+
icon: "/icons/companies/sqlserver.svg",
43+
url: "/",
44+
},
45+
{
46+
name: "CockroachDB",
47+
icon: "/icons/companies/cockroachdb.svg",
48+
url: "/",
49+
},
50+
{
51+
name: "PlanetScale",
52+
icon: "/icons/companies/planetscale.svg",
53+
url: "/",
54+
},
55+
{
56+
name: "MongoDB",
57+
icon: "/icons/technologies/mongodbsimple.svg",
58+
url: "/",
59+
},
60+
],
61+
};
62+
const frameworks = {
63+
title: "Selected Frameworks",
64+
description:
65+
"Easy to integrate into your framework of choice, Prisma simplifies database access, saves repetitive CRUD boilerplate and increases type safety.",
66+
list: [
67+
{
68+
name: "React",
69+
icon: "/icons/technologies/react.svg",
70+
url: "/react",
71+
},
72+
{
73+
name: "Next.js",
74+
icon: "/icons/technologies/nextjs.svg",
75+
url: "/nextjs",
76+
},
77+
{
78+
name: "NestJS",
79+
icon: "/icons/technologies/nestjs.svg",
80+
url: "/nestjs",
81+
},
82+
{
83+
name: "Apollo",
84+
icon: "/icons/technologies/apollo.svg",
85+
url: "/apollo",
86+
},
87+
{
88+
name: "Hapi",
89+
icon: "/icons/technologies/hapi.svg",
90+
url: "/hapi",
91+
},
92+
{
93+
name: "GraphQL",
94+
icon: "/icons/technologies/graphql.svg",
95+
url: "/graphql",
96+
},
97+
{
98+
name: "ExpressJS",
99+
icon: "/icons/technologies/express.svg",
100+
url: "/express",
101+
},
102+
{
103+
name: "Redwood",
104+
icon: "/icons/technologies/redwoodjs.svg",
105+
url: "/redwood",
106+
},
107+
],
108+
};
109+
const twoCol = [
110+
{
111+
content: (
112+
<div className="flex flex-col gap-4">
113+
<div className="flex flex-col gap-1">
114+
<h5 className="text-base uppercase font-sans-display stretch-display font-bold text-foreground-orm-strong mb-1">
115+
Editor Integration
116+
</h5>
117+
<h2 className="text-foreground-neutral stretch-display text-4xl font-black! font-sans-display my-0">
118+
Autocomplete your way to success
119+
</h2>
120+
</div>
121+
<p className="text-foreground-neutral-weak! text-base">
122+
The best code is the code that writes itself. Prisma Client gives you
123+
a fantastic autocomplete experience so you can move quickly and be
124+
sure you don't write an invalid query. Our obsession with type safety
125+
means you can rest assured that your code works as expected, every
126+
time.
127+
</p>
128+
<Button variant="orm" size="3xl" className="w-fit" href="/studio">
129+
<span>Get started in 5 minutes</span>
130+
</Button>
131+
</div>
132+
),
133+
imageUrl: "/illustrations/client/client_0",
134+
imageAlt: "Autocomplete your way to success",
135+
mobileImageUrl: null,
136+
mobileImageAlt: null,
137+
logos: null,
138+
useDefaultLogos: false,
139+
visualPosition: "left" as const,
140+
visualType: "image" as const,
141+
},
142+
{
143+
content: (
144+
<div className="flex flex-col gap-4">
145+
<div className="flex flex-col gap-1">
146+
<h5 className="text-base uppercase font-sans-display stretch-display font-bold text-foreground-orm-strong mb-1">
147+
TypedSQL
148+
</h5>
149+
<h2 className="text-foreground-neutral stretch-display text-4xl font-black! font-sans-display my-0">
150+
Fully type-safe raw SQL
151+
</h2>
152+
</div>
153+
<p className="text-foreground-neutral-weak! text-base">
154+
Execute SQL queries directly against your database without losing the
155+
benefits of Prisma’s type-checking and auto-completion. TypedSQL
156+
leverages the capabilities of Prisma Client to write raw SQL queries
157+
that are type-checked at compile time.
158+
</p>
159+
<Button variant="orm" size="3xl" className="w-fit" href="/typedsql">
160+
<span>Learn more about TypedSQL</span>
161+
</Button>
162+
</div>
163+
),
164+
imageUrl: "/illustrations/client/client_1",
165+
imageAlt: "Fully type-safe raw SQL",
166+
mobileImageUrl: null,
167+
mobileImageAlt: null,
168+
logos: null,
169+
useDefaultLogos: false,
170+
noShadow: true,
171+
visualPosition: "right" as const,
172+
visualType: "image" as const,
173+
},
174+
];
175+
176+
export default function Client() {
177+
return (
178+
<main className="flex-1 w-screen bg-background-default">
179+
<div className="hero relative w-full -mt-33 pt-45 pb-8 flex flex-col gap-8 px-4">
180+
<div className="bg-[linear-gradient(180deg,var(--color-foreground-orm)_0%,var(--color-background-default)_100%)] absolute inset-0 z-0 overflow-hidden opacity-20" />
181+
<div className="flex flex-col gap-4 relative z-1">
182+
<h5 className="stretch-display font-sans-display mx-auto w-fit my-0 text-foreground-orm-strong uppercase">
183+
Prisma Client
184+
</h5>
185+
<h1 className="stretch-display text-6xl font-bold text-center font-sans-display z-2 relative max-w-223 mx-auto">
186+
Intuitive database client for TypeScript and Node.js
187+
<br />
188+
Database Migrations
189+
</h1>
190+
</div>
191+
<p className="max-w-200 w-full mx-auto text-center relative z-1">
192+
The Prisma Client works seamlessly across languages and databases.
193+
Ship faster by writing less SQL. Avoid mistakes with a fully type-safe
194+
API tailored specifically for your app.
195+
</p>
196+
</div>
197+
<div className="px-4 relative z-1">
198+
<div className="max-w-[1200px] mx-auto pt-12">
199+
<API />
200+
</div>
201+
</div>
202+
<div
203+
className={cn(
204+
"-mb-12 px-4 relative",
205+
"before:absolute before:content-[''] before:inset-0 before:opacity-20",
206+
"before:bg-[linear-gradient(0deg,var(--color-foreground-orm-weak)_0%,var(--color-background-default)_100%)]",
207+
)}
208+
>
209+
<div className="relative z-1">
210+
<CardSection cardSection={twoCol} />
211+
</div>
212+
</div>
213+
<div
214+
className={cn(
215+
"py-12 px-4 relative",
216+
"before:absolute before:content-[''] before:inset-0 before:opacity-20 before:z-0",
217+
"before:bg-[linear-gradient(180deg,var(--color-foreground-orm-weak)_0%,var(--color-background-default)_100%)]",
218+
)}
219+
>
220+
<div className="max-w-[1200px] mx-auto z-1 relative flex flex-col gap-40">
221+
<div className="cards mx-auto max-w-222 flex flex-col gap-6">
222+
<h2 className="text-foreground-neutral text-center stretch-display text-4xl font-black! font-sans-display mt-0 mb-4">
223+
Works with your favourite
224+
<br />
225+
databases and framework
226+
</h2>
227+
<Card className="bg-background-default flex-row! md:gap-8! justify-between items-center md:p-8 flex-wrap">
228+
<h5 className="text-xl font-sans-display stretch-display font-bold md:w-min text-foreground-neutral">
229+
{databases.title}
230+
</h5>
231+
<div className="flex gap-1 flex-wrap">
232+
{databases.list.map((db) => (
233+
<Technology text={db.name} url={db.url}>
234+
<Action
235+
color="neutral"
236+
size="4xl"
237+
key={db.name}
238+
className="h-[75px]! w-[75px]! hover:bg-background-neutral-strong"
239+
>
240+
<img src={db.icon} alt={db.name} />
241+
</Action>
242+
</Technology>
243+
))}
244+
</div>
245+
</Card>
246+
<Card className="bg-background-default md:gap-8! justify-between items-start md:items-center md:p-8">
247+
<div className="flex gap-2 md:gap-6 items-start md:items-center md:flex-row flex-col">
248+
<h5 className="text-xl font-sans-display stretch-display font-bold md:w-min text-foreground-neutral">
249+
{frameworks.title}
250+
</h5>
251+
<p className="text-base text-foreground-neutral-weak">
252+
{frameworks.description}
253+
</p>
254+
</div>
255+
<div className="flex gap-1 flex-wrap">
256+
{frameworks.list.map((fw) => (
257+
<Technology text={fw.name} url={fw.url}>
258+
<Action
259+
color="neutral"
260+
size="4xl"
261+
key={fw.name}
262+
className="h-[75px]! w-[75px]! hover:bg-background-neutral-strong"
263+
>
264+
<img src={fw.icon} alt={fw.name} />
265+
</Action>
266+
</Technology>
267+
))}
268+
</div>
269+
</Card>
270+
<div className="flex gap-4 mx-auto w-fit flex-wrap justify-center">
271+
<Button variant="default-stronger" size="3xl">
272+
<span>Browse examples on GitHub</span>
273+
<i className="fa-brands fa-github ml-2" />
274+
</Button>
275+
<Button variant="orm" size="3xl">
276+
<span>Prisma in your stack</span>
277+
<i className="fa-regular fa-arrow-right ml-2" />
278+
</Button>
279+
</div>
280+
</div>
281+
<div className="grid md:grid-cols-2 gap-12 lg:gap-23">
282+
<div className="grid grid-rows-[auto_auto_1fr_auto]">
283+
<h5 className="text-base uppercase font-sans-display stretch-display font-bold text-foreground-orm-strong mb-1">
284+
Prisma Studio
285+
</h5>
286+
<h3 className="text-foreground-neutral text-3xl stretch-display font-sans-display mb-4">
287+
Visual database browser
288+
</h3>
289+
<p className="text-foreground-neutral-weak text-md mb-8">
290+
Prisma Studio is the easiest way to explore and manipulate data
291+
in your Prisma projects. Understand your data by browsing across
292+
tables, filter, paginate, traverse relations and edit your data
293+
with safety.
294+
</p>
295+
<Button variant="orm" size="3xl" className="w-fit" href="/studio">
296+
<span>Learn more about Prisma Studio</span>
297+
<i className="fa-regular fa-arrow-right ml-2" />
298+
</Button>
299+
</div>
300+
<div className="grid grid-rows-[auto_auto_1fr_auto]">
301+
<h5 className="text-base uppercase font-sans-display stretch-display font-bold text-foreground-orm-strong mb-1">
302+
Prisma Migrate
303+
</h5>
304+
<h3 className="text-foreground-neutral text-3xl stretch-display font-sans-display mb-4">
305+
Hassle-free migrations
306+
</h3>
307+
<p className="text-foreground-neutral-weak text-md mb-8">
308+
Prisma Migrate auto-generates SQL migrations from your Prisma
309+
schema. These migration files are fully customizable, giving you
310+
full control and ultimate flexibility — from local development
311+
to production environments.
312+
</p>
313+
<Button
314+
variant="orm"
315+
size="3xl"
316+
className="w-fit"
317+
href="/migrate"
318+
>
319+
<span>Learn more about Prisma Migrate</span>
320+
<i className="fa-regular fa-arrow-right ml-2" />
321+
</Button>
322+
</div>
323+
</div>
324+
</div>
325+
</div>
326+
</main>
327+
);
328+
}

apps/site/src/app/pricing/pricing-hero-plans.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export function PricingHeroPlans({
7070
<SelectTrigger className="h-10 min-w-[90px] border-stroke-neutral bg-background-default text-sm text-foreground-neutral-weak">
7171
<SelectValue />
7272
</SelectTrigger>
73-
<SelectContent>
73+
<SelectContent alignItemWithTrigger={false}>
7474
{Object.entries(symbols).map(([code, symbol]) => (
7575
<SelectItem key={code} value={code}>
7676
{code} {symbol}
@@ -88,7 +88,9 @@ export function PricingHeroPlans({
8888
<article
8989
key={planKey}
9090
className={`relative rounded-2xl border ${
91-
highlighted ? "border-stroke-ppg" : "border-stroke-neutral-weak"
91+
highlighted
92+
? "border-stroke-ppg"
93+
: "border-stroke-neutral-weak"
9294
} bg-background-default p-5 text-foreground-neutral shadow-[0px_18px_42px_0px_rgba(23,43,77,0.08)]`}
9395
>
9496
{highlighted && (
@@ -129,7 +131,8 @@ export function PricingHeroPlans({
129131
<p className="m-0 mt-3 text-4xl leading-tight font-sans-display slashed-zero tabular-nums [font-variation-settings:'wght'_800] text-foreground-neutral">
130132
{plan.price[currency]}
131133
<span className="text-2xl text-foreground-neutral-weak">
132-
{ ' ' } / month
134+
{" "}
135+
/ month
133136
</span>
134137
</p>
135138
<Button
@@ -165,8 +168,8 @@ export function PricingHeroPlans({
165168
})}
166169
</div>
167170
<div className="mt-8 text-center text-xs text-foreground-ppg-weak">
168-
*An operation is each time you interact with your database, no matter
169-
the compute time.
171+
*An operation is each time you interact with your database, no
172+
matter the compute time.
170173
<br />
171174
We count the Prisma ORM queries you make, not the SQL statements you
172175
run.{" "}
@@ -181,7 +184,8 @@ export function PricingHeroPlans({
181184
about our pricing model.
182185
</div>
183186
<p className="mt-2 mb-0 text-center text-xs text-foreground-neutral-weak">
184-
All quotas and limits are shared across all databases in your account.
187+
All quotas and limits are shared across all databases in your
188+
account.
185189
</p>
186190
</div>
187191
</section>

0 commit comments

Comments
 (0)