From d36ee6ab531966b41cd0907fa9ee3c243bd274d3 Mon Sep 17 00:00:00 2001 From: zvspany Date: Sun, 29 Mar 2026 20:56:44 +0200 Subject: [PATCH] feat(homepage): update profile preview and payment methods display --- app/page.tsx | 130 +++++++++++++++++++++++++++++++++----------------- next-env.d.ts | 2 +- 2 files changed, 88 insertions(+), 44 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index db7231b..99db1a5 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,32 +1,52 @@ import Link from "next/link"; +import QRCode from "qrcode"; +import { PaymentMethodType } from "@prisma/client"; import { auth } from "@/lib/auth"; +import { buildPaymentUri } from "@/lib/payment-uri"; +import { ProfileHeader } from "@/components/public/profile-header"; +import { PaymentMethodCard } from "@/components/public/payment-method-card"; import { buttonStyles } from "@/components/ui/button"; -const previewRows = [ +const previewProfile = { + displayName: "Your Name", + username: "yourname", + bio: "A public page where people can copy your payment details in one place.", + avatarUrl: null, +}; + +const previewMethodsBase: Array<{ + id: string; + type: PaymentMethodType; + label: string; + value: string; + network: string | null; + description: string | null; + isVisible: boolean; +}> = [ { - title: "PayPal", - meta: "paypal.me/alexdev", - value: "alexdev", - actions: "copy · open" + id: "preview-monero", + type: "BITCOIN", + label: "Bitcoin", + value: "bc1qrp8uudvq5rr5l0nuepkxvxayyny2ws2w0m8jz3", + network: null, + description: null, + isVisible: true, }, { - title: "USDT", - meta: "TRC20", - value: "TQ6...k2S", - actions: "copy · qr" + id: "preview-paypal", + type: "PAYPAL", + label: "PayPal", + value: "https://paypal.me/yourname", + network: null, + description: null, + isVisible: true, }, - { - title: "Bank Transfer", - meta: "IBAN", - value: "DE89 3704 0044 0532 0130 00", - actions: "copy" - } ]; const howItWorks = [ "Create an account and choose your public username.", "Add payment methods and optional social/contact links.", - "Share your profile URL so people can copy details or scan QR." + "Share your profile URL so people can copy details or scan QR.", ]; const whyPayMe = [ @@ -34,11 +54,36 @@ const whyPayMe = [ "No processing: PayMe does not execute transactions.", "Self-hosted: run it on your own infrastructure.", "Open source: inspect and modify everything.", - "Privacy-friendly: minimal profile data, no tracking layer built in." + "Privacy-friendly: minimal profile data, no tracking layer built in.", ]; export default async function HomePage() { const session = await auth(); + const previewMethods = await Promise.all( + previewMethodsBase.map(async (method) => { + const qrPayload = buildPaymentUri( + method.type, + method.value, + method.network, + ); + let qrDataUrl: string | null = null; + + try { + qrDataUrl = await QRCode.toDataURL(qrPayload, { + margin: 1, + width: 220, + }); + } catch { + qrDataUrl = null; + } + + return { + ...method, + qrPayload, + qrDataUrl, + }; + }), + ); const primaryHref = session?.user ? "/dashboard" : "/register"; const primaryLabel = session?.user ? "Open dashboard" : "Create your profile"; @@ -52,8 +97,9 @@ export default async function HomePage() { One public page for every way people can pay you.

- Self-hosted payment profile pages for creators, freelancers, and OSS maintainers. No custody. No - transaction processing. Just clear payment details and links. + Self-hosted payment profile pages for creators, freelancers, and OSS + maintainers. No custody. No transaction processing. Just clear + payment details and links.

@@ -62,7 +108,8 @@ export default async function HomePage() { href={primaryHref} className={buttonStyles({ variant: "primary", - className: "relative -top-1 min-h-[3.1rem] min-w-[13rem] justify-center px-6" + className: + "relative -top-1 min-h-[3.1rem] min-w-[13rem] justify-center px-6", })} > {primaryLabel} @@ -71,7 +118,8 @@ export default async function HomePage() { href="#example" className={buttonStyles({ variant: "secondary", - className: "relative -top-1 min-h-[3.1rem] min-w-[10.75rem] justify-center px-5" + className: + "relative -top-1 min-h-[3.1rem] min-w-[10.75rem] justify-center px-5", })} style={{ marginLeft: "14px" }} > @@ -83,31 +131,27 @@ export default async function HomePage() {

Profile preview

-

How a public PayMe profile is presented.

+

+ How a public PayMe profile is presented. +

-
-
-

Public profile

-

Alex Rivera

-

@alexdev

-

Open source maintainer. Donations keep maintenance sustainable.

-
+
+ -
    - {previewRows.map((row) => ( -
  • -
    -
    -

    {row.title}

    -

    {row.meta}

    -

    {row.value}

    -
    -

    {row.actions}

    -
    -
  • - ))} -
+
+

Payment Methods

+
+ {previewMethods.map((method) => ( + + ))} +
+
diff --git a/next-env.d.ts b/next-env.d.ts index c4b7818..9edff1c 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.