diff --git a/apps/api/src/modules/listings/repositories/listing-repository.js b/apps/api/src/modules/listings/repositories/listing-repository.js index 2ffcb48..5299018 100644 --- a/apps/api/src/modules/listings/repositories/listing-repository.js +++ b/apps/api/src/modules/listings/repositories/listing-repository.js @@ -262,6 +262,7 @@ export function createListingRepository(db) { conditionCode: result.condition.code, marketValueMinor: override?.valueMinor ?? valuation?.valueMinor ?? null, marketValueCurrency: override?.currency ?? valuation?.currency ?? null, + marketValueUpdatedAt: override?.createdAt ?? valuation?.calculatedAt ?? null, }; }, diff --git a/apps/web/src/components/organisms/CollectibleDetail.stories.js b/apps/web/src/components/organisms/CollectibleDetail.stories.js index b7766b2..a8586bd 100644 --- a/apps/web/src/components/organisms/CollectibleDetail.stories.js +++ b/apps/web/src/components/organisms/CollectibleDetail.stories.js @@ -11,6 +11,7 @@ export const ListingDetail = { status: "AVAILABLE", priceMinor: 11500, marketValueMinor: 12000, + marketValueUpdatedAt: "2026-09-10T00:00:00.000Z", condition: "Near Mint", description: "A clean collector copy with a clear front and back.", facts: [ @@ -34,3 +35,14 @@ export const ProductWithoutImages = { facts: [{ label: "Category", value: "Collectible merchandise" }], }, }; + +export const SoldListing = { + args: { + title: "Pikachu ex", + status: "SOLD", + priceMinor: 11500, + marketValueMinor: 12000, + marketValueUpdatedAt: "2026-09-10T00:00:00.000Z", + condition: "Near Mint", + }, +}; diff --git a/apps/web/src/components/organisms/CollectibleDetail.vue b/apps/web/src/components/organisms/CollectibleDetail.vue index 8824dfb..250b30d 100644 --- a/apps/web/src/components/organisms/CollectibleDetail.vue +++ b/apps/web/src/components/organisms/CollectibleDetail.vue @@ -10,6 +10,7 @@ defineProps({ priceMinor: { type: Number, default: null }, marketValueMinor: { type: Number, default: null }, marketValueCurrency: { type: String, default: "USD" }, + marketValueUpdatedAt: { type: [String, Date], default: null }, condition: { type: String, default: "" }, description: { type: String, default: "" }, facts: { type: Array, default: () => [] }, @@ -28,7 +29,7 @@ defineProps({

{{ title }}

{{ description }}

- +
+

+ Market value updated + +

{{ fact.label }}
diff --git a/apps/web/src/pages/ListingDetailPage.vue b/apps/web/src/pages/ListingDetailPage.vue index 6a427ec..5e01fd0 100644 --- a/apps/web/src/pages/ListingDetailPage.vue +++ b/apps/web/src/pages/ListingDetailPage.vue @@ -37,6 +37,7 @@ onMounted(async () => { :price-minor="listing.askingPriceMinor" :market-value-minor="listing.marketValueMinor" :market-value-currency="listing.marketValueCurrency" + :market-value-updated-at="listing.marketValueUpdatedAt" :condition=" listing.conditionName ? `${listing.conditionName} (${listing.conditionCode})` diff --git a/docs/IMPLEMENTATION-STATUS.md b/docs/IMPLEMENTATION-STATUS.md index 3ccfbd6..b25deef 100644 --- a/docs/IMPLEMENTATION-STATUS.md +++ b/docs/IMPLEMENTATION-STATUS.md @@ -175,6 +175,7 @@ Remaining roadmap areas are approved external provider credentials/adapters, bro - Review and listing is now an extracted `ReviewListStep` molecule covering physical-copy selection and asking-price confirmation while preserving existing draft creation and publication lifecycle behavior. - The guided inventory workflow now has extracted Product, Source Mapping, Physical Copy, Images, Pricing, and Review/List frontend stages, each with colocated Storybook coverage. - Public catalog sorting now supports latest manual/calculated market value low-to-high and high-to-low, with null values placed last. +- Public listing detail now shows market-value freshness and suppresses asking price for sold listings, with Storybook coverage for sold and valued states. - Public catalog filters now collapse behind an accessible mobile disclosure, show an active-filter count, and provide a reset action while preserving URL synchronization. ## Local Commands diff --git a/packages/contracts/public-listing.js b/packages/contracts/public-listing.js index c0b079b..d894868 100644 --- a/packages/contracts/public-listing.js +++ b/packages/contracts/public-listing.js @@ -13,6 +13,7 @@ export function toPublicListingDto(listing) { askingPriceMinor: listing.askingPriceMinor, marketValueMinor: listing.marketValueMinor ?? null, marketValueCurrency: listing.marketValueCurrency ?? null, + marketValueUpdatedAt: toIsoString(listing.marketValueUpdatedAt), status: listing.status, notes: listing.notes ?? null, images: listing.images ?? [],