This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
.review-list-step {
|
||||||
|
align-content: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-list-step__intro {
|
||||||
|
margin: var(--space-2) 0 0;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
font-size: var(--text-sm);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import ReviewListStep from './ReviewListStep.vue';
|
||||||
|
|
||||||
|
export default { title: 'Molecules/ReviewListStep', component: ReviewListStep };
|
||||||
|
|
||||||
|
const inventory = [
|
||||||
|
{ id: 'copy-1', status: 'ACTIVE' },
|
||||||
|
{ id: 'copy-2', status: 'ARCHIVED' },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Ready = {
|
||||||
|
args: { inventoryItemId: 'copy-1', askingPrice: '2499', inventory, isSaving: false },
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Empty = {
|
||||||
|
args: { inventoryItemId: '', askingPrice: '', inventory, isSaving: false },
|
||||||
|
};
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
inventoryItemId: { type: String, required: true },
|
||||||
|
askingPrice: { type: String, required: true },
|
||||||
|
inventory: { type: Array, required: true },
|
||||||
|
isSaving: { type: Boolean, default: false },
|
||||||
|
});
|
||||||
|
|
||||||
|
defineEmits(['update:inventoryItemId', 'update:askingPrice', 'submit']);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<form id="workflow-listing" class="showcase-panel review-list-step" @submit.prevent="$emit('submit')">
|
||||||
|
<div>
|
||||||
|
<p class="catalog-kicker">Step 6</p>
|
||||||
|
<h2>Review and List</h2>
|
||||||
|
<p class="review-list-step__intro">Confirm the physical copy and asking price. Images, condition, and product identity are checked before publishing.</p>
|
||||||
|
</div>
|
||||||
|
<label class="fixture-label" for="listing-inventory">Inventory copy</label>
|
||||||
|
<select
|
||||||
|
id="listing-inventory"
|
||||||
|
:value="inventoryItemId"
|
||||||
|
class="fixture-input"
|
||||||
|
required
|
||||||
|
@change="$emit('update:inventoryItemId', $event.target.value)"
|
||||||
|
>
|
||||||
|
<option value="" disabled>Select a physical copy</option>
|
||||||
|
<option v-for="item in inventory" :key="item.id" :value="item.id">
|
||||||
|
{{ item.id }} · {{ item.status }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<label class="fixture-label" for="listing-price">Asking price (cents)</label>
|
||||||
|
<input
|
||||||
|
id="listing-price"
|
||||||
|
:value="askingPrice"
|
||||||
|
class="fixture-input"
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
required
|
||||||
|
@input="$emit('update:askingPrice', $event.target.value)"
|
||||||
|
/>
|
||||||
|
<button class="button button--primary" type="submit" :disabled="isSaving">
|
||||||
|
Create listing draft
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@use './ReviewListStep.scss';
|
||||||
|
</style>
|
||||||
@@ -9,6 +9,7 @@ import ProviderMappingStep from "@/components/molecules/ProviderMappingStep.vue"
|
|||||||
import InventoryCopyStep from "@/components/molecules/InventoryCopyStep.vue";
|
import InventoryCopyStep from "@/components/molecules/InventoryCopyStep.vue";
|
||||||
import InventoryImagesStep from "@/components/molecules/InventoryImagesStep.vue";
|
import InventoryImagesStep from "@/components/molecules/InventoryImagesStep.vue";
|
||||||
import PricingReviewStep from "@/components/molecules/PricingReviewStep.vue";
|
import PricingReviewStep from "@/components/molecules/PricingReviewStep.vue";
|
||||||
|
import ReviewListStep from "@/components/molecules/ReviewListStep.vue";
|
||||||
import {
|
import {
|
||||||
createAdminInventory,
|
createAdminInventory,
|
||||||
createAdminProduct,
|
createAdminProduct,
|
||||||
@@ -714,41 +715,15 @@ onMounted(load);
|
|||||||
@update:condition-id="conditionId = $event"
|
@update:condition-id="conditionId = $event"
|
||||||
@submit="createInventory"
|
@submit="createInventory"
|
||||||
/>
|
/>
|
||||||
<form id="workflow-listing" class="showcase-panel" @submit.prevent="createListing">
|
<ReviewListStep
|
||||||
<h2>Create listing draft</h2>
|
:inventory-item-id="listingInventoryId"
|
||||||
<label class="fixture-label" for="listing-inventory"
|
:asking-price="askingPrice"
|
||||||
>Inventory copy</label
|
:inventory="inventory"
|
||||||
>
|
:is-saving="isSaving"
|
||||||
<select
|
@update:inventory-item-id="listingInventoryId = $event"
|
||||||
id="listing-inventory"
|
@update:asking-price="askingPrice = $event"
|
||||||
v-model="listingInventoryId"
|
@submit="createListing"
|
||||||
class="fixture-input"
|
|
||||||
required
|
|
||||||
>
|
|
||||||
<option value="" disabled>Select a physical copy</option>
|
|
||||||
<option v-for="item in inventory" :key="item.id" :value="item.id">
|
|
||||||
{{ item.id }} · {{ item.status }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<label class="fixture-label" for="listing-price"
|
|
||||||
>Asking price (cents)</label
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
id="listing-price"
|
|
||||||
v-model="askingPrice"
|
|
||||||
class="fixture-input"
|
|
||||||
type="number"
|
|
||||||
min="1"
|
|
||||||
required
|
|
||||||
/>
|
/>
|
||||||
<button
|
|
||||||
class="button button--primary"
|
|
||||||
type="submit"
|
|
||||||
:disabled="isSaving"
|
|
||||||
>
|
|
||||||
Create listing
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<form class="showcase-panel" @submit.prevent="recordSale">
|
<form class="showcase-panel" @submit.prevent="recordSale">
|
||||||
<h2>Record sale</h2>
|
<h2>Record sale</h2>
|
||||||
<label class="fixture-label" for="sale-inventory">Inventory copy</label>
|
<label class="fixture-label" for="sale-inventory">Inventory copy</label>
|
||||||
|
|||||||
@@ -172,6 +172,8 @@ Remaining roadmap areas are approved external provider credentials/adapters, bro
|
|||||||
- Physical inventory creation is now an extracted `InventoryCopyStep` molecule with Product and condition selection states, while preserving the existing seller-scoped create-copy API workflow.
|
- Physical inventory creation is now an extracted `InventoryCopyStep` molecule with Product and condition selection states, while preserving the existing seller-scoped create-copy API workflow.
|
||||||
- Image management is now surfaced as an extracted `InventoryImagesStep` molecule with missing-image status and direct links to the existing upload/processing manager route.
|
- Image management is now surfaced as an extracted `InventoryImagesStep` molecule with missing-image status and direct links to the existing upload/processing manager route.
|
||||||
- Pricing is now an extracted `PricingReviewStep` molecule covering observations, provider refresh, and reasoned manual overrides while preserving existing pricing API behavior.
|
- Pricing is now an extracted `PricingReviewStep` molecule covering observations, provider refresh, and reasoned manual overrides while preserving existing pricing API behavior.
|
||||||
|
- 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 catalog sorting now supports latest manual/calculated market value low-to-high and high-to-low, with null values placed last.
|
||||||
- Public catalog filters now collapse behind an accessible mobile disclosure, show an active-filter count, and provide a reset action while preserving URL synchronization.
|
- Public catalog filters now collapse behind an accessible mobile disclosure, show an active-filter count, and provide a reset action while preserving URL synchronization.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user