diff --git a/src/pages/RiderCardPage.tsx b/src/pages/RiderCardPage.tsx index ca93777..f7f3ae2 100644 --- a/src/pages/RiderCardPage.tsx +++ b/src/pages/RiderCardPage.tsx @@ -41,6 +41,7 @@ import { useQuery } from '@tanstack/react-query'; import { genUserName } from '@/lib/genUserName'; import { cn } from '@/lib/utils'; import type { NostrEvent } from '@nostrify/nostrify'; +import { QRCodeCanvas } from '@/components/ui/qrcode'; import { Printer, Download, Copy, Palette, Check, Building2, @@ -87,19 +88,24 @@ const STYLES = ['Street', 'Park', 'Vert', 'Bowl', 'DIY', 'All-terrain'] as const function shortNpub(pubkey: string) { if (!pubkey) return '—'; const npub = nip19.npubEncode(pubkey); - return `${npub.slice(0, 10)}…${npub.slice(-4)}`; + return `${npub.slice(0, 12)}…${npub.slice(-6)}`; } -function riderLicenseId(pubkey: string) { - // Deterministic license ID from pubkey — human-readable, not a secret - const n = parseInt(pubkey.slice(0, 8), 16) % 9000000 + 1000000; - return `SS-${n}`; +function fullNpub(pubkey: string) { + if (!pubkey) return ''; + return nip19.npubEncode(pubkey); } function memberSince(createdAt: number) { return new Date(createdAt * 1000).getFullYear().toString(); } +// Verification URL — scanning this on a phone opens the profile on skate-spots.org +function verifyUrl(pubkey: string) { + if (!pubkey) return 'https://skate-spots.org'; + return `https://skate-spots.org/${nip19.npubEncode(pubkey)}`; +} + // ─── Badge award event type ─────────────────────────────────────────────────── interface BadgeAward { witnessName: string; @@ -119,6 +125,7 @@ interface CardData { nip05?: string; avatar?: string; pubkey: string; + npub: string; style: string; skills: string[]; sponsors: string; @@ -130,7 +137,6 @@ interface CardData { zapsReceived: number; eventsCreated: number; memberYear: string; - licenseId: string; receivedBadges: BadgeAward[]; // Park issuerName: string; @@ -167,175 +173,202 @@ function useWitnessName(pubkey: string) { } // ─── Card visual: Rider front ───────────────────────────────────────────────── +// Layout is STRICTLY pixel-fixed to match the 340×214px card container. +// No flex-1 / flex-grow — every row has a fixed pixel height. function RiderFront({ d }: { d: CardData }) { - // Only show first 2 witnessed badges on the card itself - const witnessedBadges = d.receivedBadges.slice(0, 3); + const witnessedBadges = d.receivedBadges.slice(0, 2); + const qrUrl = verifyUrl(d.pubkey); return ( -