From 40d889ac4ea21fc63cad0083b8a26653b7afc454 Mon Sep 17 00:00:00 2001 From: jckbtchr <77942319+jckbtchr-bot@users.noreply.github.com> Date: Fri, 29 May 2026 16:15:31 -0500 Subject: [PATCH 1/2] Add broker contact flow to Punk marketplace status module Rework Punk/Detail/Market.vue: move Top bid to the left cell with the Place-bid form beneath it, Listing to the right cell with a new Contact broker button beneath it, and surface the owner's wallet last-active time (from the indexer) under the listing state. New Market/BrokerContact.vue: a Contact broker popover with email capture (client-side only for now) and a co-branded "Canon" preview, toggled via a floating control that appears beneath the dialog while open. New Market/BrokerLogo.vue inlines the broker wordmark. Co-Authored-By: Claude Opus 4.8 --- .../app/components/Punk/Detail/Market.vue | 105 +++++-- .../Punk/Detail/Market/BrokerContact.vue | 280 ++++++++++++++++++ .../Punk/Detail/Market/BrokerLogo.vue | 40 +++ 3 files changed, 394 insertions(+), 31 deletions(-) create mode 100644 punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue create mode 100644 punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue diff --git a/punks.auction/app/components/Punk/Detail/Market.vue b/punks.auction/app/components/Punk/Detail/Market.vue index f47c75b4..4d37c27a 100644 --- a/punks.auction/app/components/Punk/Detail/Market.vue +++ b/punks.auction/app/components/Punk/Detail/Market.vue @@ -15,6 +15,35 @@ class="market-panel" >
+
+
Top bid
+
+ + by + + + +
+
+ None +
+ +
+ +
+
+
Listing
@@ -32,23 +61,17 @@ > Not for sale
-
-
-
Top bid
-
- - by - - - -
-
- None -
+ Wallet last active {{ ownerLastActiveAgo }} +

+ +
+ +
@@ -123,20 +146,12 @@ .

-
- - -
+ @@ -228,6 +243,26 @@ const canBuy = computed(() => { ) }) +// Owner's wallet last-active, sourced from the indexer's tx-from tracking, so a +// broker can gauge how reachable the holder is. Custody set covers vault/stash; +// the EOA drives the last-active lookup. +const ownerAddresses = computed(() => { + const set = new Set
() + if (resolvedOwner.value) set.add(resolvedOwner.value) + if (nativeOwner.value) set.add(nativeOwner.value) + return [...set] +}) +const { stats: ownerStats } = useAccountStats({ + addresses: ownerAddresses, + eoa: () => resolvedOwner.value ?? undefined, +}) +const ownerLastActiveIso = computed(() => + ownerStats.value.lastActiveAt + ? new Date(ownerStats.value.lastActiveAt * 1000).toISOString() + : undefined, +) +const ownerLastActiveAgo = useTimeAgo(ownerLastActiveIso) + let refreshToken = 0 async function refresh() { @@ -386,6 +421,16 @@ function sameAddress(a?: Address | string | null, b?: Address | string | null) { border: 0; } +.last-active { + margin: var(--size-1) 0 0; + font-size: var(--font-xs); + color: var(--text-dim); +} + +.cell-action { + margin-top: var(--size-4); +} + .label { margin-bottom: var(--size-1); color: var(--text-dim); @@ -404,8 +449,6 @@ function sameAddress(a?: Address | string | null, b?: Address | string | null) { align-items: center; gap: var(--size-2); flex-wrap: wrap; - padding-top: var(--size-3); - border-top: var(--border); } .action-group { diff --git a/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue b/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue new file mode 100644 index 00000000..da26aa8d --- /dev/null +++ b/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue @@ -0,0 +1,280 @@ + + + + + diff --git a/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue b/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue new file mode 100644 index 00000000..693fb2e2 --- /dev/null +++ b/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue @@ -0,0 +1,40 @@ + + + From 3004f743e88c9d95c9461c18e00ac42ee81ec21a Mon Sep 17 00:00:00 2001 From: jckbtchr <77942319+jckbtchr-bot@users.noreply.github.com> Date: Fri, 29 May 2026 17:05:45 -0500 Subject: [PATCH 2/2] Extract broker brand to runtime config Move the broker name and logo SVG out of BrokerLogo.vue into runtimeConfig.public.broker (default "Canon"), overridable per deployment via NUXT_PUBLIC_BROKER_NAME / NUXT_PUBLIC_BROKER_LOGO. BrokerLogo.vue now renders the configured SVG and BrokerContact.vue reads the name from config. Documented both env vars in .env.example. Co-Authored-By: Claude Opus 4.8 --- punks.auction/.env.example | 6 +++ .../Punk/Detail/Market/BrokerContact.vue | 6 ++- .../Punk/Detail/Market/BrokerLogo.vue | 46 +++++++------------ punks.auction/nuxt.config.ts | 8 ++++ 4 files changed, 35 insertions(+), 31 deletions(-) diff --git a/punks.auction/.env.example b/punks.auction/.env.example index 1e5c987f..1421a93e 100644 --- a/punks.auction/.env.example +++ b/punks.auction/.env.example @@ -10,3 +10,9 @@ NUXT_PUBLIC_EVM_WALLET_CONNECT_PROJECT_ID= # Public indexer base URL (Ponder/Postgres GraphQL endpoint). Defaults to the # shared production indexer in nuxt.config.ts; override per environment. NUXT_PUBLIC_INDEXER_URL=https://indexer.punksmarket.app + +# Broker brand shown in the "branded" Contact-broker preview. Defaults to +# "Canon" in nuxt.config.ts. NUXT_PUBLIC_BROKER_LOGO is inline SVG markup — +# use fill="currentColor" so it inherits the surrounding text color. +NUXT_PUBLIC_BROKER_NAME=Canon +NUXT_PUBLIC_BROKER_LOGO= diff --git a/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue b/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue index da26aa8d..aa58100b 100644 --- a/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue +++ b/punks.auction/app/components/Punk/Detail/Market/BrokerContact.vue @@ -109,8 +109,10 @@ const submitted = ref(false) // Demo affordance: flips the dialog to a co-branded broker preview. Persists // across reopen so it can be shown/screen-shared without re-toggling. const branded = ref(false) -// Named broker in the branded preview; generic in the standard version. -const brokerName = computed(() => (branded.value ? 'Canon' : 'a broker')) +// Named broker (from runtime config) in the branded preview; generic in the +// standard version. +const broker = useRuntimeConfig().public.broker as { name: string; logo: string } +const brokerName = computed(() => (branded.value ? broker.name : 'a broker')) // Float the version toggle just below the dialog box: present only while the // popover is open and anchored to the live dialog rect, so it reads as a diff --git a/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue b/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue index 693fb2e2..e39ff0e8 100644 --- a/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue +++ b/punks.auction/app/components/Punk/Detail/Market/BrokerLogo.vue @@ -1,40 +1,28 @@ + + diff --git a/punks.auction/nuxt.config.ts b/punks.auction/nuxt.config.ts index 087902ab..d94ace1d 100644 --- a/punks.auction/nuxt.config.ts +++ b/punks.auction/nuxt.config.ts @@ -66,6 +66,14 @@ export default defineNuxtConfig({ // shared indexer that backs both punksmarket.app and this app. // Override with NUXT_PUBLIC_INDEXER_URL. indexerUrl: 'https://indexer.punksmarket.app', + // Broker brand shown in the "branded" Contact-broker preview. Override + // per deployment with NUXT_PUBLIC_BROKER_NAME / NUXT_PUBLIC_BROKER_LOGO. + // `logo` is inline SVG markup; use `fill="currentColor"` so it inherits + // the surrounding text color. + broker: { + name: 'Canon', + logo: '', + }, evm: { walletConnectProjectId: '', chains: {