From c417244ae7b22ec58a228812331382803263916a Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Thu, 26 Mar 2026 13:53:57 +0000 Subject: [PATCH 1/6] First version of ORM --- apps/site/src/app/orm/page.tsx | 273 ++++++++++++++++++ .../homepage/card-section/card-section.tsx | 7 +- .../homepage/card-section/logo-grid.tsx | 72 +++-- apps/site/src/components/orm/info-stats.tsx | 48 +++ packages/eclipse/src/components/button.tsx | 2 + 5 files changed, 372 insertions(+), 30 deletions(-) create mode 100644 apps/site/src/app/orm/page.tsx create mode 100644 apps/site/src/components/orm/info-stats.tsx diff --git a/apps/site/src/app/orm/page.tsx b/apps/site/src/app/orm/page.tsx new file mode 100644 index 0000000000..840f30a03e --- /dev/null +++ b/apps/site/src/app/orm/page.tsx @@ -0,0 +1,273 @@ +import Antigravity from "../../components/homepage/antigravity"; +import type { Metadata } from "next"; +import { + SITE_HOME_DESCRIPTION, + SITE_HOME_TITLE, +} from "../../lib/blog-metadata"; +import { Button, Separator } from "@prisma/eclipse"; +import { Bento } from "@/components/homepage/bento"; +import { CardSection } from "@/components/homepage/card-section/card-section"; +import review from "../../data/homepage.json"; +import Testimonials from "../../components/homepage/testimonials"; +import { InfoStats } from "@/components/orm/info-stats"; + +const statsSection = [ + { + icon: "fa-brands fa-github", + number: "45k+", + text: "Stars on GitHub", + link: "https://github.com/prisma/prisma", + }, + { + icon: "fa-regular fa-rocket-launch", + number: "250k+", + text: "Active developers", + link: "https://www.npmjs.com/package/prisma", + }, +]; +const badge_list = [ + { + title: "supported languages", + list: [ + { label: "JavaScript", url: "/js" }, + { label: "TypeScript", url: "/ts" }, + ], + }, + { + title: "community-supported languages", + list: [ + { label: "Python", url: "/py" }, + { label: "Dart", url: "/dart" }, + { label: "GO", url: "/GO" }, + { label: "Rust", url: "/rust" }, + ], + }, +]; +const CardFooter = () => ( + <> + +
+ {badge_list.map((badge: any, index: number) => ( +
+
+ {badge.title} +
+ {badge.list && + badge.list.map((item: any) => ( + + ))} +
+ ))} +
+ +); +const twoCol = [ + { + content: ( + <> +
+
+ Why Prisma ORM +
+

+ Postgres that
fits your stack. +

+
+

+ Database workflows can feel brittle and error-prone. Prisma ORM + increases productivity and confidence when working with databases and + makes workflows like data modeling, migrations and querying easy. +

+ + ), + imageUrl: null, + imageAlt: null, + mobileImageUrl: null, + mobileImageAlt: null, + logos: null, + useDefaultLogos: true, + visualPosition: "right" as const, + visualType: "video" as const, + footer: , + }, + { + content: ( + <> +

+ Postgres that
fits your stack. +

+

+ Database workflows can feel brittle and error-prone. Prisma ORM + increases productivity and confidence when working with databases and + makes workflows like data modeling, migrations and querying easy. +

+ + ), + imageUrl: null, + imageAlt: null, + mobileImageUrl: null, + mobileImageAlt: null, + color: "orm", + logos: null, + useDefaultLogos: true, + visualPosition: "right" as const, + visualType: "logoGrid" as const, + }, + { + content: ( + <> +

+ Real Postgres.
Better experience. +

+

+ The PostgreSQL millions know and trust in production, ready in seconds + with zero configuration. Automatic backups, observability and + compliance. +

+ + ), + imageUrl: "/illustrations/homepage/real_orm", + imageAlt: "Real Postgres", + mobileImageUrl: "/illustrations/homepage/real_orm_mobile", + mobileImageAlt: "Real orm mobile", + logos: null, + useDefaultLogos: false, + visualPosition: "left" as const, + visualType: "image" as const, + }, +]; +export const metadata: Metadata = { + title: SITE_HOME_TITLE, + description: SITE_HOME_DESCRIPTION, +}; + +export default function ORM() { + return ( +
+
+
+
+

+ Next-generation Node.js and TypeScript ORM +

+

+ Real Postgres with the developer experience and infrastructure to + ship faster. +

+
+ + +
+
+
+
+ {statsSection?.map((stat: any, index: number) => ( + + ))} +
+
+
+ +
+
+
+
+
+

+ Build anything. +
+ Deploy instantly. +

+
+

+ Give your users instant production-ready Postgres, create + databases, add a built-in data browser, and personalize it. +

+ +
+
+
+
+ {review?.testimonials?.length > 0 && ( +
+
+
+
+
+ +
+
+
+
+ )} +
+
+
+
+

+ Ready to try Prisma? +

+

+ Deploy a Postgres database instantly. +

+
+
+ + +
+
+ Free to get started, no credit card needed. +
+
+
+
+
+ ); +} diff --git a/apps/site/src/components/homepage/card-section/card-section.tsx b/apps/site/src/components/homepage/card-section/card-section.tsx index 3537d0b6f8..4b5553d17f 100644 --- a/apps/site/src/components/homepage/card-section/card-section.tsx +++ b/apps/site/src/components/homepage/card-section/card-section.tsx @@ -12,9 +12,11 @@ interface TwoColumnItem { mobileImageUrl: string | null; mobileImageAlt: string | null; logos: any[] | null; + footer?: ReactNode; + color?: "orm" | "ppg"; useDefaultLogos: boolean; visualPosition: "left" | "right"; - visualType: "logoGrid" | "image"; + visualType: "logoGrid" | "image" | "video"; } interface CardSectionProps { @@ -59,7 +61,7 @@ export const CardSection = ({ cardSection }: CardSectionProps) => { )} > {item.visualType === "logoGrid" && item.useDefaultLogos && ( - + )} {item.visualType === "image" && item.imageUrl && ( <> @@ -87,6 +89,7 @@ export const CardSection = ({ cardSection }: CardSectionProps) => { )} + {item.footer && <>{item.footer}} ))} diff --git a/apps/site/src/components/homepage/card-section/logo-grid.tsx b/apps/site/src/components/homepage/card-section/logo-grid.tsx index 8a7daf78db..38445a58d6 100644 --- a/apps/site/src/components/homepage/card-section/logo-grid.tsx +++ b/apps/site/src/components/homepage/card-section/logo-grid.tsx @@ -5,6 +5,7 @@ import { useState, useEffect, memo } from "react"; import defaultLogosData from "./default-logos.json"; import { useTheme } from "@prisma-docs/ui/components/theme-provider"; import GlowCursor from "@/components/homepage/glow-cursor"; +import { cn } from "@/lib/cn"; // Inline keyframe animations const AnimationStyles = () => ( @@ -31,6 +32,7 @@ const AnimationStyles = () => ( // Inline LogoBar component const LogoBar = ({ logos, + color, direction = "right", pauseOnHover = false, duplicateCount = 3, @@ -54,7 +56,12 @@ const LogoBar = ({ @@ -80,6 +87,7 @@ interface Logo { interface LogoGridProps { logos?: Logo[]; type?: "spotlight" | "track"; + color?: "orm" | "ppg"; } // ============================================================================ @@ -119,33 +127,40 @@ LogoImage.displayName = "LogoImage"; // SPOTLIGHT MODE COMPONENT // ============================================================================ -const SpotlightMode = memo(({ logos }: { logos: Logo[] }) => { - const logoSize = 50; - const visibleLogos = logos.slice(0, 21); - - return ( - -
- {/* Logo grid */} -
-
- {visibleLogos.map((logo, index) => ( - - - - ))} +const SpotlightMode = memo( + ({ logos, color }: { logos: Logo[]; color?: "orm" | "ppg" }) => { + const logoSize = 50; + const visibleLogos = logos.slice(0, 21); + + return ( + +
+ {/* Logo grid */} +
+
+ {visibleLogos.map((logo, index) => ( + + + + ))} +
-
- - ); -}); + + ); + }, +); SpotlightMode.displayName = "SpotlightMode"; @@ -193,6 +208,7 @@ TrackMode.displayName = "TrackMode"; export const LogoGrid = ({ logos: propLogos, type = "spotlight", + color = undefined, }: LogoGridProps) => { const logos = propLogos && propLogos.length > 0 ? propLogos : defaultLogosData; @@ -201,9 +217,9 @@ export const LogoGrid = ({ <> {type === "track" ? ( - + ) : ( - + )} ); diff --git a/apps/site/src/components/orm/info-stats.tsx b/apps/site/src/components/orm/info-stats.tsx new file mode 100644 index 0000000000..a5182ace66 --- /dev/null +++ b/apps/site/src/components/orm/info-stats.tsx @@ -0,0 +1,48 @@ +"use client"; +import { FunctionComponent } from "react"; +import AnimatedNumbers from "react-animated-numbers"; +import { cn } from "@/lib/cn"; +export const InfoStats: FunctionComponent<{ + icon?: any; + number?: string; + text?: string; + link?: string; +}> = ({ icon, number, text, link }) => { + const match = number?.match(/^(\d+)(\D.*)?$/); + + return ( + match && ( + + ) + ); +}; diff --git a/packages/eclipse/src/components/button.tsx b/packages/eclipse/src/components/button.tsx index 256477d76d..608a74b33a 100644 --- a/packages/eclipse/src/components/button.tsx +++ b/packages/eclipse/src/components/button.tsx @@ -9,6 +9,8 @@ const buttonVariants = cva( variant: { ppg: "bg-background-ppg-reverse text-foreground-ppg-reverse hover:bg-background-ppg-reverse-strong shadow-box-low", orm: "bg-background-orm-reverse text-foreground-orm-reverse hover:bg-background-orm-reverse-strong shadow-box-low", + "orm-reverse": + "bg-background-orm text-foreground-orm hover:bg-background-orm-strong shadow-box-low", "default-stronger": "bg-background-neutral text-foreground-neutral hover:bg-background-neutral-strong border border-stroke-neutral-strong", default: From 03103c1d174cebb30c2345c89a1169b9ca5a98aa Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Thu, 26 Mar 2026 13:54:56 +0000 Subject: [PATCH 2/6] fix badge spacings --- apps/site/src/app/orm/page.tsx | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/site/src/app/orm/page.tsx b/apps/site/src/app/orm/page.tsx index 840f30a03e..668c71fae1 100644 --- a/apps/site/src/app/orm/page.tsx +++ b/apps/site/src/app/orm/page.tsx @@ -52,17 +52,19 @@ const CardFooter = () => (
{badge.title}
- {badge.list && - badge.list.map((item: any) => ( - - ))} +
+ {badge.list && + badge.list.map((item: any) => ( + + ))} +
))}
From 5b904e7748c2cba2a55c15998dbfcec42ad9fec7 Mon Sep 17 00:00:00 2001 From: Carla Goncalves Date: Thu, 26 Mar 2026 16:27:15 +0000 Subject: [PATCH 3/6] Add client page --- .../site/public/icons/technologies/vscode.svg | 2 +- .../illustrations/orm/collaborative.svg | 60 ++++ .../illustrations/orm/collaborative_light.svg | 60 ++++ apps/site/public/illustrations/orm/data.svg | 181 ++++++++++ .../public/illustrations/orm/data_light.svg | 181 ++++++++++ apps/site/public/illustrations/orm/ide.svg | 73 ++++ .../public/illustrations/orm/ide_light.svg | 73 ++++ apps/site/public/illustrations/orm/orm_1.svg | 325 ++++++++++++++++++ .../public/illustrations/orm/orm_1_light.svg | 325 ++++++++++++++++++ apps/site/public/illustrations/orm/orm_2.svg | 71 ++++ .../public/illustrations/orm/orm_2_light.svg | 71 ++++ .../public/illustrations/orm/thumbnail.png | Bin 0 -> 64123 bytes .../public/illustrations/orm/typesafe.svg | 74 ++++ .../illustrations/orm/typesafe_light.svg | 74 ++++ apps/site/src/app/global.css | 44 +++ apps/site/src/app/orm/page.tsx | 274 ++++++++++++--- apps/site/src/components/homepage/bento.tsx | 60 ++-- .../homepage/card-section/card-section.tsx | 4 +- .../homepage/card-section/logo-grid.tsx | 72 ++-- .../homepage/testimonials/index.tsx | 22 +- .../testimonials/testimonial-item.tsx | 11 +- packages/eclipse/src/components/action.tsx | 4 +- packages/ui/package.json | 1 + packages/ui/src/components/youtube-player.tsx | 116 +++++++ pnpm-lock.yaml | 18 + 25 files changed, 2079 insertions(+), 117 deletions(-) create mode 100644 apps/site/public/illustrations/orm/collaborative.svg create mode 100644 apps/site/public/illustrations/orm/collaborative_light.svg create mode 100644 apps/site/public/illustrations/orm/data.svg create mode 100644 apps/site/public/illustrations/orm/data_light.svg create mode 100644 apps/site/public/illustrations/orm/ide.svg create mode 100644 apps/site/public/illustrations/orm/ide_light.svg create mode 100644 apps/site/public/illustrations/orm/orm_1.svg create mode 100644 apps/site/public/illustrations/orm/orm_1_light.svg create mode 100644 apps/site/public/illustrations/orm/orm_2.svg create mode 100644 apps/site/public/illustrations/orm/orm_2_light.svg create mode 100644 apps/site/public/illustrations/orm/thumbnail.png create mode 100644 apps/site/public/illustrations/orm/typesafe.svg create mode 100644 apps/site/public/illustrations/orm/typesafe_light.svg create mode 100644 packages/ui/src/components/youtube-player.tsx diff --git a/apps/site/public/icons/technologies/vscode.svg b/apps/site/public/icons/technologies/vscode.svg index 97ca79854d..1d3d60733a 100644 --- a/apps/site/public/icons/technologies/vscode.svg +++ b/apps/site/public/icons/technologies/vscode.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/apps/site/public/illustrations/orm/collaborative.svg b/apps/site/public/illustrations/orm/collaborative.svg new file mode 100644 index 0000000000..b0dcf4b8e8 --- /dev/null +++ b/apps/site/public/illustrations/orm/collaborative.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/collaborative_light.svg b/apps/site/public/illustrations/orm/collaborative_light.svg new file mode 100644 index 0000000000..9a31577bcb --- /dev/null +++ b/apps/site/public/illustrations/orm/collaborative_light.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/data.svg b/apps/site/public/illustrations/orm/data.svg new file mode 100644 index 0000000000..cad84b6374 --- /dev/null +++ b/apps/site/public/illustrations/orm/data.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/data_light.svg b/apps/site/public/illustrations/orm/data_light.svg new file mode 100644 index 0000000000..0b2f4c6dcb --- /dev/null +++ b/apps/site/public/illustrations/orm/data_light.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/ide.svg b/apps/site/public/illustrations/orm/ide.svg new file mode 100644 index 0000000000..20466d3255 --- /dev/null +++ b/apps/site/public/illustrations/orm/ide.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/site/public/illustrations/orm/ide_light.svg b/apps/site/public/illustrations/orm/ide_light.svg new file mode 100644 index 0000000000..0109d93445 --- /dev/null +++ b/apps/site/public/illustrations/orm/ide_light.svg @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/site/public/illustrations/orm/orm_1.svg b/apps/site/public/illustrations/orm/orm_1.svg new file mode 100644 index 0000000000..79328521f6 --- /dev/null +++ b/apps/site/public/illustrations/orm/orm_1.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/orm_1_light.svg b/apps/site/public/illustrations/orm/orm_1_light.svg new file mode 100644 index 0000000000..de4b32f7ad --- /dev/null +++ b/apps/site/public/illustrations/orm/orm_1_light.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/orm_2.svg b/apps/site/public/illustrations/orm/orm_2.svg new file mode 100644 index 0000000000..c01e156d78 --- /dev/null +++ b/apps/site/public/illustrations/orm/orm_2.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/orm_2_light.svg b/apps/site/public/illustrations/orm/orm_2_light.svg new file mode 100644 index 0000000000..33e133d9f0 --- /dev/null +++ b/apps/site/public/illustrations/orm/orm_2_light.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/thumbnail.png b/apps/site/public/illustrations/orm/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..eb51934c56eb95a9b785fc2eb3c86ac142d4c384 GIT binary patch literal 64123 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 $dN)hxsH9JZL>7e*R3v6V#^sbXWVlSK#A69ve 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 literal 0 HcmV?d00001 diff --git a/apps/site/public/illustrations/orm/typesafe.svg b/apps/site/public/illustrations/orm/typesafe.svg new file mode 100644 index 0000000000..d53be4ddae --- /dev/null +++ b/apps/site/public/illustrations/orm/typesafe.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/public/illustrations/orm/typesafe_light.svg b/apps/site/public/illustrations/orm/typesafe_light.svg new file mode 100644 index 0000000000..fad44e51de --- /dev/null +++ b/apps/site/public/illustrations/orm/typesafe_light.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/site/src/app/global.css b/apps/site/src/app/global.css index 799fd38d4c..de0bcc039f 100644 --- a/apps/site/src/app/global.css +++ b/apps/site/src/app/global.css @@ -123,6 +123,14 @@ body { transition: background 0.3s ease; } +.box.orm { + background: linear-gradient( + 180deg, + var(--color-background-default) 0%, + var(--color-background-orm) 262.5% + ) !important; +} + .box-visible { opacity: 1; transform: scale(1) translateY(0); @@ -175,6 +183,31 @@ body { var(--color-teal-400) 360deg ); } +/* Dark mode hover effect */ +.box.orm:hover::before { + background: conic-gradient( + from var(--angle, 0deg) at 50% 50%, + var(--color-indigo-400) 0deg, + rgba(22, 163, 148, 0.3) 30deg, + rgba(22, 29, 43, 0.8) 90deg, + rgba(22, 29, 43, 0.8) 270deg, + rgba(22, 163, 148, 0.3) 330deg, + var(--color-indigo-400) 360deg + ); +} + +/* Light mode hover effect */ +[data-theme="light"] .box.orm:hover::before { + background: conic-gradient( + from var(--angle, 0deg) at 50% 50%, + var(--color-indigo-400) 0deg, + rgba(22, 163, 148, 0.3) 30deg, + rgba(229, 231, 235, 0.8) 90deg, + rgba(229, 231, 235, 0.8) 270deg, + rgba(22, 163, 148, 0.3) 330deg, + var(--color-indigo-400) 360deg + ); +} .box:hover { transform: translateY(-1px) scale(1.005); @@ -192,3 +225,14 @@ body { .running { animation-play-state: running; } + +.link-btn { + color: var(--color-background-orm-reverse-strong); +} +.link-btn:hover { + color: var(--color-foreground-orm-reverse); +} +.link-btn > *:not(i) { + text-decoration: underline; + text-underline-offset: 3px; +} diff --git a/apps/site/src/app/orm/page.tsx b/apps/site/src/app/orm/page.tsx index 668c71fae1..955ecb6b7d 100644 --- a/apps/site/src/app/orm/page.tsx +++ b/apps/site/src/app/orm/page.tsx @@ -1,15 +1,17 @@ -import Antigravity from "../../components/homepage/antigravity"; import type { Metadata } from "next"; import { SITE_HOME_DESCRIPTION, SITE_HOME_TITLE, } from "../../lib/blog-metadata"; -import { Button, Separator } from "@prisma/eclipse"; +import { Action, Button, Card, Separator } from "@prisma/eclipse"; import { Bento } from "@/components/homepage/bento"; import { CardSection } from "@/components/homepage/card-section/card-section"; import review from "../../data/homepage.json"; import Testimonials from "../../components/homepage/testimonials"; import { InfoStats } from "@/components/orm/info-stats"; +import { cn } from "@/lib/cn"; +import { Card as FeatureCard } from "@/components/homepage/bento"; +import { YouTubePlayer } from "@prisma-docs/ui/components/youtube-player"; const statsSection = [ { @@ -46,9 +48,12 @@ const badge_list = [ const CardFooter = () => ( <> -

- {badge_list.map((badge: any, index: number) => ( -
+
+ {badge_list.map((badge: any) => ( +
{badge.title}
@@ -75,11 +80,11 @@ const twoCol = [ content: ( <>
-
+
Why Prisma ORM
-

- Postgres that
fits your stack. +

+ Delightful DB workflows

@@ -94,57 +99,167 @@ const twoCol = [ mobileImageUrl: null, mobileImageAlt: null, logos: null, + other: ( + + ), useDefaultLogos: true, visualPosition: "right" as const, - visualType: "video" as const, + visualType: "other" as const, footer: , }, { content: ( - <> -

- Postgres that
fits your stack. +
), imageUrl: null, imageAlt: null, mobileImageUrl: null, mobileImageAlt: null, - color: "orm", + color: "orm" as const, logos: null, useDefaultLogos: true, visualPosition: "right" as const, visualType: "logoGrid" as const, }, +]; +const twoCol_2 = [ { content: ( - <> -

- Real Postgres.
Better experience. -

+
+
+
+ Prisma Benchmarks +
+

+ Prisma vs other ORMs +

+

- The PostgreSQL millions know and trust in production, ready in seconds - with zero configuration. Automatic backups, observability and - compliance. + A meaningful comparison of database query latencies across database + providers and ORM libraries in the Node.js & TypeScript ecosystem.

- +
), - imageUrl: "/illustrations/homepage/real_orm", - imageAlt: "Real Postgres", - mobileImageUrl: "/illustrations/homepage/real_orm_mobile", - mobileImageAlt: "Real orm mobile", + imageUrl: "/illustrations/orm/orm_1", + imageAlt: "ORM illustration", + mobileImageUrl: "/illustrations/orm/orm_1", + mobileImageAlt: "ORM illustration", logos: null, - useDefaultLogos: false, + useDefaultLogos: true, visualPosition: "left" as const, visualType: "image" as const, }, + { + content: ( +
+
+
+ Prisma Client +
+

+ Type-safe database client +

+
+

+ Prisma Client is a query builder that’s tailored to your schema. We + designed its API to be intuitive, both for SQL veterans and developers + brand new to databases. The auto-completion helps you figure out your + query without the need for documentation. +

+ + Learn more + + +
+ ), + imageUrl: "/illustrations/orm/orm_2", + imageAlt: "ORM illustration", + mobileImageUrl: "/illustrations/orm/orm_2", + mobileImageAlt: "ORM illustration", + color: "orm" as const, + logos: null, + useDefaultLogos: true, + visualPosition: "right" as const, + visualType: "image" as const, + }, +]; + +const twoCol_3 = [ + { + icon: "/icons/technologies/vscode.svg", + title: "Extra ergonomy in VS Code", + description: + "Auto-completion, linting, formatting and more help Prisma developers in VSCode stay confident and productive.", + btn: { + url: "/", + label: "Download Prisma VSCode Extension", + icon: "fa-regular fa-arrow-up-right", + }, + }, + { + icon: "/icons/technologies/ts.svg", + title: "Make fewer errors with TypeScript", + description: + "Prisma ORM provides the strongest type-safety guarantees of all the ORMs in the TypeScript ecosystem.", + btn: { + url: "/", + label: "Read comparison with TypeORM", + icon: "fa-regular fa-arrow-up-right", + }, + }, ]; + +const features = [ + { + title: "Manage databases", + subtitle: "Created directly in your IDE.", + image: "/illustrations/orm/ide", + alt: "Manage dbs", + icon: "fa-light fa-screwdriver-wrench", + link: "/mcp", + }, + { + title: "Type-safety", + subtitle: "Code faster with auto-completion and type safety.", + image: "/illustrations/orm/typesafe", + alt: "Type-safe queries", + icon: "fa-light fa-message-text", + link: "https://prisma.io/docs/orm/prisma-client/type-safety", + }, + { + title: "Data model you can read", + subtitle: "The Prisma schema is intuitive and easy to use", + image: "/illustrations/orm/collaborative", + alt: "Collaborative work", + icon: "fa-light fa-screen-users", + link: "https://console.prisma.io", + }, + { + title: "Browse your data", + subtitle: "Explore, filter, and edit your data with an interface.", + image: "/illustrations/orm/data", + alt: "Data browsing", + icon: "fa-light fa-magnifying-glass-arrow-right", + link: "/studio", + }, +]; + export const metadata: Metadata = { title: SITE_HOME_TITLE, description: SITE_HOME_DESCRIPTION, @@ -187,7 +302,7 @@ export default function ORM() {

-
+
{statsSection?.map((stat: any, index: number) => (
-
-
-
-

- Build anything. -
- Deploy instantly. -

-
-

- Give your users instant production-ready Postgres, create - databases, add a built-in data browser, and personalize it. -

- -
+
+
+ +
+ {twoCol_3.map((stat, index) => ( +
+ + {stat.title} + +

+ {stat.title} +

+

+ {stat.description} +

+ +
+ ))} +
+
+
+
+
+

+ Streamline your +
+ development workflow +

+
+

+ Integrate Prisma into your development ecosystem and focus on your + team’s core competencies +

+
+
+
+ {features.map((card: any) => ( + + ))} +
+
+ {review?.testimonials?.length > 0 && (
@@ -235,6 +397,7 @@ export default function ORM() { /> @@ -243,24 +406,25 @@ export default function ORM() {
)} -
+

- Ready to try Prisma? + Ready to get started?

-

- Deploy a Postgres database instantly. +

+ Start from scratch, add Prisma ORM to your existing project, or + explore how to build an app using your favorite framework.

diff --git a/apps/site/src/components/homepage/bento.tsx b/apps/site/src/components/homepage/bento.tsx index a55c2f25ba..16a08757c7 100644 --- a/apps/site/src/components/homepage/bento.tsx +++ b/apps/site/src/components/homepage/bento.tsx @@ -29,20 +29,29 @@ interface BentoProps { bentoSection: { boxes: BentoBox[]; }; + hero?: React.ReactNode; + color?: "orm" | "ppg"; } -const HeroContent = ({ className = "" }: { className?: string }) => ( -
-

- Your database, right in your workflow -

-
-); +const HeroContent = ({ + className = "", + hero, +}: { + className?: string; + hero?: React.ReactNode; +}) => + hero || ( +
+

+ Your database, right in your workflow +

+
+ ); const useResponsiveLayout = () => { const [isDesktop, setIsDesktop] = useState(true); @@ -57,7 +66,7 @@ const useResponsiveLayout = () => { return { isDesktop }; }; -export const Bento = ({ bentoSection }: BentoProps) => { +export const Bento = ({ bentoSection, hero, color }: BentoProps) => { const { isDesktop } = useResponsiveLayout(); // Transform Sanity data to internal CardData format @@ -76,29 +85,37 @@ export const Bento = ({ bentoSection }: BentoProps) => { return (
{/* Desktop Layout (961+): Original 3-row layout with text in middle */} - + {isDesktop ? ( <>
{CARDS.filter((card) => card.row === "top").map((card) => ( - + ))}
{firstCenterCard && ( - + )} {secondCenterCard && ( - + )}
) : (
{CARDS.map((card) => ( - + ))}
)} @@ -108,9 +125,10 @@ export const Bento = ({ bentoSection }: BentoProps) => { interface CardProps { card: CardData; + color?: "orm" | "ppg"; } -const Card = ({ card }: CardProps) => { +export const Card = ({ card, color }: CardProps) => { const cardRef = useRef(null); const isCenterCard = ["4", "5"].includes(card.id); const { resolvedTheme } = useTheme(); @@ -156,12 +174,13 @@ const Card = ({ card }: CardProps) => { "box-visible", "w-full", isCenterCard && "w-full md:order-0", + color, )} onMouseMove={handleMouseMove} onMouseLeave={handleMouseLeave} >
- +
@@ -181,7 +200,6 @@ const Card = ({ card }: CardProps) => { ? `${card.image}_light.svg` : `${card.image}.svg` } - alt={card.title} className="px-4 z-2 pt-0 pb-0 min-w-full min-h-[60%] object-fill object-[top_left] [mask-image:linear-gradient(to_bottom,rgba(0,0,0,1)_60%,transparent_90%)] [-webkit-mask-image:linear-gradient(to_bottom,rgba(0,0,0,1)_60%,transparent_90%)]" /> diff --git a/apps/site/src/components/homepage/card-section/card-section.tsx b/apps/site/src/components/homepage/card-section/card-section.tsx index 4b5553d17f..f20234f8f1 100644 --- a/apps/site/src/components/homepage/card-section/card-section.tsx +++ b/apps/site/src/components/homepage/card-section/card-section.tsx @@ -14,9 +14,10 @@ interface TwoColumnItem { logos: any[] | null; footer?: ReactNode; color?: "orm" | "ppg"; + other?: ReactNode; useDefaultLogos: boolean; visualPosition: "left" | "right"; - visualType: "logoGrid" | "image" | "video"; + visualType: "logoGrid" | "image" | "other"; } interface CardSectionProps { @@ -60,6 +61,7 @@ export const CardSection = ({ cardSection }: CardSectionProps) => { item.visualType === "logoGrid" ? "max-w-full" : "lg:w-full", )} > + {item.other && item.visualType === "other" && item.other} {item.visualType === "logoGrid" && item.useDefaultLogos && ( )} diff --git a/apps/site/src/components/homepage/card-section/logo-grid.tsx b/apps/site/src/components/homepage/card-section/logo-grid.tsx index 38445a58d6..5de56907d4 100644 --- a/apps/site/src/components/homepage/card-section/logo-grid.tsx +++ b/apps/site/src/components/homepage/card-section/logo-grid.tsx @@ -38,6 +38,7 @@ const LogoBar = ({ duplicateCount = 3, }: { logos: Logo[]; + color?: "orm" | "ppg"; direction?: "left" | "right"; pauseOnHover?: boolean; duplicateCount?: number; @@ -168,36 +169,49 @@ SpotlightMode.displayName = "SpotlightMode"; // TRACK MODE COMPONENT // ============================================================================ -const TrackMode = memo(({ logos }: { logos: Logo[] }) => { - // Split logos into 3 even groups - const logosPerBar = Math.ceil(logos.length / 3); - const logosBar1 = logos.slice(0, logosPerBar); - const logosBar2 = logos.slice(logosPerBar, logosPerBar * 2); - const logosBar3 = logos.slice(logosPerBar * 2); +const TrackMode = memo( + ({ logos, color }: { logos: Logo[]; color?: "orm" | "ppg" }) => { + // Split logos into 3 even groups + const logosPerBar = Math.ceil(logos.length / 3); + const logosBar1 = logos.slice(0, logosPerBar); + const logosBar2 = logos.slice(logosPerBar, logosPerBar * 2); + const logosBar3 = logos.slice(logosPerBar * 2); - return ( -
-
- - - -
- ); -}); + return ( +
+
+ + + +
+ ); + }, +); TrackMode.displayName = "TrackMode"; diff --git a/apps/site/src/components/homepage/testimonials/index.tsx b/apps/site/src/components/homepage/testimonials/index.tsx index 7c72fb182d..7cd52606ea 100644 --- a/apps/site/src/components/homepage/testimonials/index.tsx +++ b/apps/site/src/components/homepage/testimonials/index.tsx @@ -8,11 +8,13 @@ type TestimonialsType = { list: Array; noShadow?: boolean; mask?: string; + color?: string; }; type TestimonialColProps = { list: TestimonialItemType[]; reverse?: boolean; + color?: string; }; const MemoizedTestimonialItem = memo(TestimonialItem); @@ -26,7 +28,7 @@ const getColumnSlices = (list: TestimonialItemType[]) => { ]; }; -const TestimonialCol = ({ list, reverse }: TestimonialColProps) => ( +const TestimonialCol = ({ color, list, reverse }: TestimonialColProps) => (
( > {list.map((testimonial: TestimonialItemType, idx) => ( ))} {list.map((testimonial: TestimonialItemType, idx) => ( @@ -59,12 +63,14 @@ const TestimonialCol = ({ list, reverse }: TestimonialColProps) => ( > {list.map((testimonial: TestimonialItemType, idx) => ( ))} {list.map((testimonial: TestimonialItemType, idx) => ( @@ -78,7 +84,7 @@ const getTabletSlices = (list: TestimonialItemType[]) => { return [list.slice(0, half), list.slice(half)]; }; -const Testimonials = ({ list, noShadow, mask }: TestimonialsType) => { +const Testimonials = ({ color, list, noShadow, mask }: TestimonialsType) => { const [col1, col2, col3] = getColumnSlices(list); const [tabletCol1, tabletCol2] = getTabletSlices(list); @@ -94,7 +100,7 @@ const Testimonials = ({ list, noShadow, mask }: TestimonialsType) => {
{/* Mobile */}
- +
{/* Tablet */} @@ -105,8 +111,8 @@ const Testimonials = ({ list, noShadow, mask }: TestimonialsType) => { "[&>*:nth-child(2)]:flex [&>*]:flex-1", )} > - - + +
{/* Desktop */} @@ -117,9 +123,9 @@ const Testimonials = ({ list, noShadow, mask }: TestimonialsType) => { "[&>*:nth-child(2)]:flex [&>*:nth-child(3)]:flex [&>*]:flex-1", )} > - - - + + +
); diff --git a/apps/site/src/components/homepage/testimonials/testimonial-item.tsx b/apps/site/src/components/homepage/testimonials/testimonial-item.tsx index 552fbe6ddc..0eafcb806f 100644 --- a/apps/site/src/components/homepage/testimonials/testimonial-item.tsx +++ b/apps/site/src/components/homepage/testimonials/testimonial-item.tsx @@ -12,6 +12,7 @@ export type TestimonialItemType = { startups?: boolean; imageAlt?: string; key?: string | number; + color?: string; }; export const TestimonialItem = ({ @@ -22,6 +23,7 @@ export const TestimonialItem = ({ imageUrl, imageAlt, startups, + color, ...rest }: TestimonialItemType) => (
) : ( company && ( - + {company} ) diff --git a/packages/eclipse/src/components/action.tsx b/packages/eclipse/src/components/action.tsx index e173a76037..fd0d2b8c6b 100644 --- a/packages/eclipse/src/components/action.tsx +++ b/packages/eclipse/src/components/action.tsx @@ -10,6 +10,7 @@ const actionVariants = cva( color: { ppg: "bg-background-ppg text-foreground-ppg", orm: "bg-background-orm text-foreground-orm", + "orm-reverse": "bg-background-orm-reverse text-foreground-orm-reverse", error: "bg-background-error text-foreground-error", success: "bg-background-success text-foreground-success", warning: "bg-background-warning text-foreground-warning", @@ -22,7 +23,8 @@ const actionVariants = cva( violet: "bg-background-violet text-foreground-violet", yellow: "bg-background-yellow text-foreground-yellow", neutral: "bg-background-neutral text-foreground-neutral", - "neutral-reversed": "bg-background-neutral-reverse text-foreground-neutral-reverse", + "neutral-reversed": + "bg-background-neutral-reverse text-foreground-neutral-reverse", }, size: { lg: "size-element-lg p-1.5", diff --git a/packages/ui/package.json b/packages/ui/package.json index bae4750462..c6ff4e0dc3 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -22,6 +22,7 @@ "clsx": "catalog:", "feed": "catalog:", "lucide-react": "catalog:", + "react-intersection-observer": "^10.0.3", "tailwind-merge": "catalog:", "vaul": "catalog:" }, diff --git a/packages/ui/src/components/youtube-player.tsx b/packages/ui/src/components/youtube-player.tsx new file mode 100644 index 0000000000..525e522e8c --- /dev/null +++ b/packages/ui/src/components/youtube-player.tsx @@ -0,0 +1,116 @@ +"use client"; +import { cn } from "../lib/cn"; +import { useEffect, useState } from "react"; +import { useInView } from "react-intersection-observer"; + +export const YouTubePlayer = ({ + video, + thumbnail, + className, + serverlessTalk = false, + autoplay = false, + overlay, + playOnView = false, +}: { + className?: string; + serverlessTalk?: boolean; + video: string; + thumbnail?: string; + playOnView?: boolean; + autoplay?: boolean; + overlay?: string; +}) => { + const [playing, setPlaying] = useState(false); + const [shouldAutoplay, setShouldAutoplay] = useState(autoplay); + const getAutoplayParams = () => + shouldAutoplay + ? `${video.includes("?") ? "&" : "?"}autoplay=1&mute=1&rel=0` + : ""; + + const { ref, inView } = useInView({ + threshold: 0.2, + triggerOnce: true, + }); + + useEffect(() => { + if (inView && playOnView && !playing) { + setPlaying(true); + setShouldAutoplay(true); + } + }, [inView, playOnView, playing]); + + return ( +
+ {overlay && ( +
+ )} + {thumbnail && !playing && ( +
{ + setPlaying(true); + setShouldAutoplay(true); + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + setPlaying(true); + setShouldAutoplay(true); + } + }} + className={cn( + "relative z-20 block w-full h-full object-cover", + serverlessTalk && "absolute z-[21] bg-[#151630]", + )} + > + thumbnail +
+ )} +
+ {video && ( +