diff --git a/apps/web/next.config.js b/apps/web/next.config.js index cd022d14..b9ea8430 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 }, @@ -84,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/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/(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/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", 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..c97e5e0e --- /dev/null +++ b/apps/web/src/components/sections/sponsors-content.ts @@ -0,0 +1,77 @@ +export interface Sponsor { + name: string; + href: string; + image: string; + imageAlt: string; + amount: string; + 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", + kind: "company", + }, + { + name: "Efferd", + href: "https://efferd.com", + image: "/companies/efferd.svg", + imageAlt: "Efferd logo", + amount: "$250 credits", + 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", + kind: "individual", + }, + { + name: "smorimoto", + href: "https://github.com/smorimoto", + image: "https://github.com/smorimoto.png?size=160", + imageAlt: "smorimoto's GitHub avatar", + amount: "$100", + 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", + kind: "individual", + }, + { + name: "Leo", + href: "https://github.com/leoisadev1", + image: "https://github.com/leoisadev1.png?size=160", + imageAlt: "Leo's GitHub avatar", + amount: "$20", + kind: "individual", + }, + { + name: "Lasse", + href: "https://github.com/lassejlv", + image: "https://github.com/lassejlv.png?size=160", + imageAlt: "Lasse's GitHub avatar", + amount: "$10", + kind: "individual", + }, + { + name: "Coobyk", + href: "https://github.com/Coobyk", + image: "https://github.com/Coobyk.png?size=160", + imageAlt: "Coobyk's GitHub avatar", + amount: "$5", + 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..ebeb9877 --- /dev/null +++ b/apps/web/src/components/sections/sponsors-section.tsx @@ -0,0 +1,100 @@ +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: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 ( + + + {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) => ( + + ))} +
+
+
+ ); +}