Files
pokemon-inventory/apps/web/src/components/organisms/CollectibleDetail.vue
T
fragginwagon b8f089a5d9 feat: reconcile application vertical slices
Backfill the completed acquisitions, sales, dashboard, pricing, search, public detail, worker, migration, contracts, validation, tests, and implementation-status changes into one verified application slice.
2026-09-09 22:12:53 -04:00

80 lines
2.3 KiB
Vue

<script setup>
import ConditionBadge from "@/components/atoms/ConditionBadge.vue";
import PriceDisplay from "@/components/atoms/PriceDisplay.vue";
import StatusBadge from "@/components/atoms/StatusBadge.vue";
import ImageGallery from "@/components/molecules/ImageGallery.vue";
defineProps({
title: { type: String, required: true },
status: { type: String, default: "" },
priceMinor: { type: Number, default: null },
marketValueMinor: { type: Number, default: null },
marketValueCurrency: { type: String, default: "USD" },
condition: { type: String, default: "" },
description: { type: String, default: "" },
facts: { type: Array, default: () => [] },
images: { type: Array, default: () => [] },
});
</script>
<template>
<article class="collectible-detail">
<div class="collectible-detail__gallery">
<ImageGallery :images="images" />
</div>
<div class="collectible-detail__identity">
<StatusBadge v-if="status" :status="status" />
<p class="catalog-kicker">Collectible identity</p>
<h1>{{ title }}</h1>
<p v-if="description" class="detail-notes">{{ description }}</p>
<div class="collectible-detail__summary">
<PriceDisplay v-if="priceMinor !== null" :amount-minor="priceMinor" />
<PriceDisplay
v-if="marketValueMinor !== null"
label="Market value"
:amount-minor="marketValueMinor"
/>
<ConditionBadge v-if="condition" :label="condition" />
</div>
<dl v-if="facts.length" class="product-facts">
<div v-for="fact in facts" :key="fact.label">
<dt>{{ fact.label }}</dt>
<dd>{{ fact.value }}</dd>
</div>
</dl>
</div>
</article>
</template>
<style scoped lang="scss">
.collectible-detail {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: var(--space-12);
align-items: start;
}
.collectible-detail__identity {
display: grid;
gap: var(--space-4);
padding-top: var(--space-6);
}
.collectible-detail__identity h1 {
margin: 0;
}
.collectible-detail__summary {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-4);
}
@media (max-width: 768px) {
.collectible-detail {
grid-template-columns: 1fr;
gap: var(--space-6);
}
.collectible-detail__identity {
padding-top: 0;
}
}
</style>