From 233cafa15bf5d9c042648af18b1f6a96d19189ad Mon Sep 17 00:00:00 2001 From: Max Katz Date: Thu, 17 Sep 2026 18:54:33 +0400 Subject: [PATCH 1/3] chore(web): add development favicon --- apps/web/next.config.js | 12 +++++++++++- apps/web/public/favicon/development.svg | 5 +++++ apps/web/public/favicon/favicon.svg | 5 ----- apps/web/public/favicon/production.svg | 5 +++++ apps/web/src/app/layout.tsx | 2 +- 5 files changed, 22 insertions(+), 7 deletions(-) create mode 100644 apps/web/public/favicon/development.svg delete mode 100644 apps/web/public/favicon/favicon.svg create mode 100644 apps/web/public/favicon/production.svg diff --git a/apps/web/next.config.js b/apps/web/next.config.js index cd022d14..931f2e44 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -4,12 +4,14 @@ import { fileURLToPath } from "node:url"; import { createMDX } from "fumadocs-mdx/next"; import "../../scripts/load-root-env.js"; -import "./src/env.js"; +import { env } from "./src/env.js"; const withMDX = createMDX(); const currentDir = dirname(fileURLToPath(import.meta.url)); const repoRoot = join(currentDir, "../.."); const remixLucideShim = join(currentDir, "src/lib/lucide-react-remix-shim.ts"); +const faviconDestination = + env.NODE_ENV === "development" ? "/favicon/development.svg" : "/favicon/production.svg"; const docsRedirects = [ { source: "/docs", destination: "/docs/introduction", permanent: true }, @@ -69,6 +71,14 @@ const config = { "@radix-ui/react-checkbox", ], }, + rewrites: async () => ({ + beforeFiles: [ + { source: "/favicon.ico", destination: faviconDestination }, + { source: "/favicon.svg", destination: faviconDestination }, + ], + afterFiles: [], + fallback: [], + }), redirects: async () => [ ...docsRedirects, { source: "/github", destination: "https://github.com/getpaykit/paykit", permanent: false }, diff --git a/apps/web/public/favicon/development.svg b/apps/web/public/favicon/development.svg new file mode 100644 index 00000000..d362128d --- /dev/null +++ b/apps/web/public/favicon/development.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/web/public/favicon/favicon.svg b/apps/web/public/favicon/favicon.svg deleted file mode 100644 index 4616b17f..00000000 --- a/apps/web/public/favicon/favicon.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/apps/web/public/favicon/production.svg b/apps/web/public/favicon/production.svg new file mode 100644 index 00000000..173ff880 --- /dev/null +++ b/apps/web/public/favicon/production.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index beefa86e..fc7a4539 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -32,7 +32,7 @@ export const metadata: Metadata = { title: { template: `%s | ${SITE_NAME}`, default: SITE_TITLE }, description: SITE_DESCRIPTION, icons: { - icon: [{ url: "/favicon/favicon.svg?v=4", type: "image/svg+xml" }], + icon: [{ url: "/favicon.svg?v=5", type: "image/svg+xml" }], apple: "/favicon/apple-touch-icon.png", }, manifest: "/favicon/site.webmanifest", From f658809ebdcc942bc016392ae137e656520cae0a Mon Sep 17 00:00:00 2001 From: Max Katz Date: Thu, 17 Sep 2026 20:18:42 +0400 Subject: [PATCH 2/3] feat(web): add sponsors to landing page --- apps/web/next.config.js | 3 +- apps/web/public/companies/efferd.svg | 4 + apps/web/public/companies/vercel-mark.svg | 3 + apps/web/src/app/(marketing)/page.tsx | 2 + apps/web/src/app/(marketing)/sponsor/page.tsx | 42 -------- .../src/components/layout/navigation-bar.tsx | 1 - apps/web/src/components/layout/section.tsx | 16 +++- .../components/sections/sponsors-content.ts | 86 +++++++++++++++++ .../components/sections/sponsors-section.tsx | 96 +++++++++++++++++++ 9 files changed, 205 insertions(+), 48 deletions(-) create mode 100644 apps/web/public/companies/efferd.svg create mode 100644 apps/web/public/companies/vercel-mark.svg delete mode 100644 apps/web/src/app/(marketing)/sponsor/page.tsx create mode 100644 apps/web/src/components/sections/sponsors-content.ts create mode 100644 apps/web/src/components/sections/sponsors-section.tsx diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 931f2e44..b9ea8430 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -94,8 +94,7 @@ const config = { destination: "https://github.com/orgs/getpaykit/projects/1", permanent: false, }, - { source: "/donate", destination: "/sponsor", permanent: true }, - { source: "/sponsors", destination: "/sponsor", permanent: true }, + { source: "/donate", destination: "/#sponsors", permanent: true }, ], }; diff --git a/apps/web/public/companies/efferd.svg b/apps/web/public/companies/efferd.svg new file mode 100644 index 00000000..95f3d81b --- /dev/null +++ b/apps/web/public/companies/efferd.svg @@ -0,0 +1,4 @@ + + + + diff --git a/apps/web/public/companies/vercel-mark.svg b/apps/web/public/companies/vercel-mark.svg new file mode 100644 index 00000000..403ecbff --- /dev/null +++ b/apps/web/public/companies/vercel-mark.svg @@ -0,0 +1,3 @@ + + + diff --git a/apps/web/src/app/(marketing)/page.tsx b/apps/web/src/app/(marketing)/page.tsx index e852d87f..9c48e308 100644 --- a/apps/web/src/app/(marketing)/page.tsx +++ b/apps/web/src/app/(marketing)/page.tsx @@ -4,6 +4,7 @@ import { FeedbackSection } from "@/components/sections/feedback-section"; import { FooterSection } from "@/components/sections/footer-section"; import { HeroSection } from "@/components/sections/hero-section"; import { demoSnippets } from "@/components/sections/readme-code-content"; +import { SponsorsSection } from "@/components/sections/sponsors-section"; import { InlineCode } from "@/components/ui/code-block-content"; import { homePageStructuredData } from "@/lib/consts"; @@ -36,6 +37,7 @@ export default function HomePage() { }} /> + diff --git a/apps/web/src/app/(marketing)/sponsor/page.tsx b/apps/web/src/app/(marketing)/sponsor/page.tsx deleted file mode 100644 index 9b555eb7..00000000 --- a/apps/web/src/app/(marketing)/sponsor/page.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import type { Metadata } from "next"; -import Link from "next/link"; -import { RiArrowLeftLine } from "react-icons/ri"; - -import { Section, SectionContent } from "@/components/layout/section"; -import { Button } from "@/components/ui/button"; - -export const metadata: Metadata = { - title: "Sponsors", - description: "PayKit sponsors page is coming soon.", - alternates: { - canonical: "/sponsor", - }, -}; - -export default function SponsorPage() { - return ( -
-
- -
-

- Coming soon -

-

- Sponsors page is not ready yet -

-

- Sponsor information and acknowledgements will be available soon. -

-
- -
-
-
-
-
- ); -} diff --git a/apps/web/src/components/layout/navigation-bar.tsx b/apps/web/src/components/layout/navigation-bar.tsx index 3d4c04d6..56307236 100644 --- a/apps/web/src/components/layout/navigation-bar.tsx +++ b/apps/web/src/components/layout/navigation-bar.tsx @@ -49,7 +49,6 @@ function NavLink({ const navTabs: NavItem[] = [ { name: "docs", href: "/docs", path: "/docs" }, { name: "blog", href: "/blog", path: "/blog" }, - { name: "sponsors", href: "/sponsor", path: "/sponsor" }, ]; const dropdownLinks: NavItem[] = [ diff --git a/apps/web/src/components/layout/section.tsx b/apps/web/src/components/layout/section.tsx index 47a5ea62..9138472c 100644 --- a/apps/web/src/components/layout/section.tsx +++ b/apps/web/src/components/layout/section.tsx @@ -17,9 +17,17 @@ export function SectionLine({ orientation }: { orientation: "horizontal" | "vert ); } -export function SectionShell({ children, className }: { children: ReactNode; className?: string }) { +export function SectionShell({ + children, + className, + id, +}: { + children: ReactNode; + className?: string; + id?: string; +}) { return ( -
+
@@ -32,14 +40,16 @@ export function SectionShell({ children, className }: { children: ReactNode; cla export function Section({ children, className, + id, last, }: { children: ReactNode; className?: string; + id?: string; last?: boolean; }) { return ( - + {!last && (
diff --git a/apps/web/src/components/sections/sponsors-content.ts b/apps/web/src/components/sections/sponsors-content.ts new file mode 100644 index 00000000..bd759ccc --- /dev/null +++ b/apps/web/src/components/sections/sponsors-content.ts @@ -0,0 +1,86 @@ +export interface Sponsor { + name: string; + href: string; + image: string; + imageAlt: string; + amount: string; + imageKind: "avatar" | "logo"; + kind: "company" | "individual"; + hideInSingleColumn?: boolean; +} + +export const sponsors: Sponsor[] = [ + { + name: "Vercel", + href: "https://vercel.com/home", + image: "/companies/vercel-mark.svg", + imageAlt: "Vercel logo", + amount: "$10,000 credits", + imageKind: "logo", + kind: "company", + }, + { + name: "Efferd", + href: "https://efferd.com", + image: "/companies/efferd.svg", + imageAlt: "Efferd logo", + amount: "$250 credits", + imageKind: "logo", + kind: "company", + }, + { + name: "MrPancakes39", + href: "https://x.com/mrpancakes39", + image: "https://pbs.twimg.com/profile_images/1991510200386207744/2Bfvjltn_200x200.jpg", + imageAlt: "MrPancakes39's X avatar", + amount: "$100", + imageKind: "avatar", + kind: "individual", + }, + { + name: "smorimoto", + href: "https://github.com/smorimoto", + image: "https://github.com/smorimoto.png?size=160", + imageAlt: "smorimoto's GitHub avatar", + amount: "$100", + imageKind: "avatar", + kind: "individual", + }, + { + name: "Ted Brine", + href: "https://github.com/tedbrine", + image: "https://github.com/tedbrine.png?size=160", + imageAlt: "Ted Brine's GitHub avatar", + amount: "$20", + imageKind: "avatar", + kind: "individual", + }, + { + name: "Leo", + href: "https://github.com/leoisadev1", + image: "https://github.com/leoisadev1.png?size=160", + imageAlt: "Leo's GitHub avatar", + amount: "$20", + imageKind: "avatar", + kind: "individual", + }, + { + name: "Lasse", + href: "https://github.com/lassejlv", + image: "https://github.com/lassejlv.png?size=160", + imageAlt: "Lasse's GitHub avatar", + amount: "$10", + imageKind: "avatar", + kind: "individual", + }, + { + name: "Coobyk", + href: "https://github.com/Coobyk", + image: "https://github.com/Coobyk.png?size=160", + imageAlt: "Coobyk's GitHub avatar", + amount: "$5", + imageKind: "avatar", + kind: "individual", + hideInSingleColumn: true, + }, +]; diff --git a/apps/web/src/components/sections/sponsors-section.tsx b/apps/web/src/components/sections/sponsors-section.tsx new file mode 100644 index 00000000..d389155f --- /dev/null +++ b/apps/web/src/components/sections/sponsors-section.tsx @@ -0,0 +1,96 @@ +import { Section, SectionContent } from "@/components/layout/section"; +import { sponsors } from "@/components/sections/sponsors-content"; +import type { Sponsor } from "@/components/sections/sponsors-content"; +import { cn } from "@/lib/utils"; + +const sponsorLinkClassName = + "group relative min-w-0 bg-background before:pointer-events-none before:absolute before:inset-0 before:bg-foreground/[0.03] before:opacity-0 before:transition-opacity hover:before:opacity-100 focus-visible:before:opacity-100 focus-visible:outline-none"; + +function CompanySponsorLink({ sponsor }: { sponsor: Sponsor }) { + return ( + + + {sponsor.imageAlt} + + + {sponsor.name} + + {sponsor.amount} + + + + ); +} + +function IndividualSponsorLink({ sponsor }: { sponsor: Sponsor }) { + return ( + + {sponsor.imageAlt} + + {sponsor.name} + + {sponsor.amount} + + + + ); +} + +export function SponsorsSection() { + const companySponsors = sponsors.filter((sponsor) => sponsor.kind === "company"); + const individualSponsors = sponsors.filter((sponsor) => sponsor.kind === "individual"); + + return ( +
+ +
+

+ Sponsors +

+
+
+ +
+
+ {companySponsors.map((sponsor) => ( + + ))} +
+
+ {individualSponsors.map((sponsor) => ( + + ))} +
+
+
+ ); +} From e2e743294b7579deb430318947e37a8cccb0ff49 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Thu, 17 Sep 2026 20:26:47 +0400 Subject: [PATCH 3/3] codex: address PR review feedback (#209) --- apps/web/src/components/sections/sponsors-content.ts | 9 --------- apps/web/src/components/sections/sponsors-section.tsx | 6 +++++- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/apps/web/src/components/sections/sponsors-content.ts b/apps/web/src/components/sections/sponsors-content.ts index bd759ccc..c97e5e0e 100644 --- a/apps/web/src/components/sections/sponsors-content.ts +++ b/apps/web/src/components/sections/sponsors-content.ts @@ -4,7 +4,6 @@ export interface Sponsor { image: string; imageAlt: string; amount: string; - imageKind: "avatar" | "logo"; kind: "company" | "individual"; hideInSingleColumn?: boolean; } @@ -16,7 +15,6 @@ export const sponsors: Sponsor[] = [ image: "/companies/vercel-mark.svg", imageAlt: "Vercel logo", amount: "$10,000 credits", - imageKind: "logo", kind: "company", }, { @@ -25,7 +23,6 @@ export const sponsors: Sponsor[] = [ image: "/companies/efferd.svg", imageAlt: "Efferd logo", amount: "$250 credits", - imageKind: "logo", kind: "company", }, { @@ -34,7 +31,6 @@ export const sponsors: Sponsor[] = [ image: "https://pbs.twimg.com/profile_images/1991510200386207744/2Bfvjltn_200x200.jpg", imageAlt: "MrPancakes39's X avatar", amount: "$100", - imageKind: "avatar", kind: "individual", }, { @@ -43,7 +39,6 @@ export const sponsors: Sponsor[] = [ image: "https://github.com/smorimoto.png?size=160", imageAlt: "smorimoto's GitHub avatar", amount: "$100", - imageKind: "avatar", kind: "individual", }, { @@ -52,7 +47,6 @@ export const sponsors: Sponsor[] = [ image: "https://github.com/tedbrine.png?size=160", imageAlt: "Ted Brine's GitHub avatar", amount: "$20", - imageKind: "avatar", kind: "individual", }, { @@ -61,7 +55,6 @@ export const sponsors: Sponsor[] = [ image: "https://github.com/leoisadev1.png?size=160", imageAlt: "Leo's GitHub avatar", amount: "$20", - imageKind: "avatar", kind: "individual", }, { @@ -70,7 +63,6 @@ export const sponsors: Sponsor[] = [ image: "https://github.com/lassejlv.png?size=160", imageAlt: "Lasse's GitHub avatar", amount: "$10", - imageKind: "avatar", kind: "individual", }, { @@ -79,7 +71,6 @@ export const sponsors: Sponsor[] = [ image: "https://github.com/Coobyk.png?size=160", imageAlt: "Coobyk's GitHub avatar", amount: "$5", - imageKind: "avatar", kind: "individual", hideInSingleColumn: true, }, diff --git a/apps/web/src/components/sections/sponsors-section.tsx b/apps/web/src/components/sections/sponsors-section.tsx index d389155f..ebeb9877 100644 --- a/apps/web/src/components/sections/sponsors-section.tsx +++ b/apps/web/src/components/sections/sponsors-section.tsx @@ -4,7 +4,7 @@ import type { Sponsor } from "@/components/sections/sponsors-content"; import { cn } from "@/lib/utils"; const sponsorLinkClassName = - "group relative min-w-0 bg-background before:pointer-events-none before:absolute before:inset-0 before:bg-foreground/[0.03] before:opacity-0 before:transition-opacity hover:before:opacity-100 focus-visible:before:opacity-100 focus-visible:outline-none"; + "group relative min-w-0 bg-background before:pointer-events-none before:absolute before:inset-0 before:bg-foreground/[0.03] before:opacity-0 before:transition-opacity hover:before:opacity-100 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring focus-visible:before:opacity-100 focus-visible:outline-none"; function CompanySponsorLink({ sponsor }: { sponsor: Sponsor }) { return ( @@ -21,7 +21,9 @@ function CompanySponsorLink({ sponsor }: { sponsor: Sponsor }) { {sponsor.imageAlt} @@ -51,7 +53,9 @@ function IndividualSponsorLink({ sponsor }: { sponsor: Sponsor }) { {sponsor.imageAlt}