feat: extract pricing review workflow step
Quality / test (push) Canceled after 0s

This commit is contained in:
2026-09-10 06:01:37 -04:00
parent ff6f3359aa
commit 82b012faa1
5 changed files with 107 additions and 88 deletions
@@ -0,0 +1,9 @@
.pricing-review-step {
align-content: start;
}
.pricing-review-step__intro {
margin: var(--space-2) 0 0;
color: var(--color-text-muted);
font-size: var(--text-sm);
}
@@ -0,0 +1,19 @@
import PricingReviewStep from './PricingReviewStep.vue';
export default { title: 'Molecules/PricingReviewStep', component: PricingReviewStep };
const inventory = [{ id: 'copy-1' }, { id: 'copy-2' }];
export const Empty = {
args: {
inventoryItemId: '', provider: 'fixture-provider', sourceIdentifier: '', observedPrice: '',
overridePrice: '', overrideReason: '', inventory, refreshStatus: '',
},
};
export const Refreshing = {
args: {
inventoryItemId: 'copy-1', provider: 'fixture-provider', sourceIdentifier: 'fixture-copy-1', observedPrice: '2500',
overridePrice: '', overrideReason: '', inventory, refreshStatus: 'PROCESSING', isSaving: true,
},
};
@@ -0,0 +1,57 @@
<script setup>
defineProps({
inventoryItemId: { type: String, required: true },
provider: { type: String, required: true },
sourceIdentifier: { type: String, required: true },
observedPrice: { type: String, required: true },
overridePrice: { type: String, required: true },
overrideReason: { type: String, required: true },
inventory: { type: Array, required: true },
refreshStatus: { type: String, default: '' },
isSaving: { type: Boolean, default: false },
});
defineEmits([
'update:inventoryItemId',
'update:provider',
'update:sourceIdentifier',
'update:observedPrice',
'update:overridePrice',
'update:overrideReason',
'calculate',
'refresh',
'override',
]);
</script>
<template>
<form id="workflow-pricing" class="showcase-panel pricing-review-step" @submit.prevent="$emit('calculate')">
<div>
<p class="catalog-kicker">Step 5</p>
<h2>Check Pricing</h2>
<p class="pricing-review-step__intro">Record a source, refresh market data, or add a reasoned private override before listing.</p>
</div>
<label class="fixture-label" for="pricing-inventory">Inventory copy</label>
<select id="pricing-inventory" :value="inventoryItemId" class="fixture-input" required @change="$emit('update:inventoryItemId', $event.target.value)">
<option value="" disabled>Select a copy</option>
<option v-for="item in inventory" :key="item.id" :value="item.id">{{ item.id }}</option>
</select>
<label class="fixture-label" for="pricing-provider">Provider</label>
<input id="pricing-provider" :value="provider" class="fixture-input" required @input="$emit('update:provider', $event.target.value)" />
<label class="fixture-label" for="pricing-source">Source identifier</label>
<input id="pricing-source" :value="sourceIdentifier" class="fixture-input" required @input="$emit('update:sourceIdentifier', $event.target.value)" />
<label class="fixture-label" for="pricing-price">Observed price (cents)</label>
<input id="pricing-price" :value="observedPrice" class="fixture-input" type="number" min="1" required @input="$emit('update:observedPrice', $event.target.value)" />
<button class="button button--primary" type="submit" :disabled="isSaving">Add observation and calculate</button>
<button class="button button--secondary" type="button" :disabled="isSaving" @click="$emit('refresh')">Refresh from provider<span v-if="refreshStatus"> ({{ refreshStatus }})</span></button>
<label class="fixture-label" for="override-price">Manual value (cents)</label>
<input id="override-price" :value="overridePrice" class="fixture-input" type="number" min="0" @input="$emit('update:overridePrice', $event.target.value)" />
<label class="fixture-label" for="override-reason">Override reason</label>
<input id="override-reason" :value="overrideReason" class="fixture-input" minlength="3" @input="$emit('update:overrideReason', $event.target.value)" />
<button class="button button--secondary" type="button" :disabled="isSaving" @click="$emit('override')">Save manual value</button>
</form>
</template>
<style scoped lang="scss">
@use './PricingReviewStep.scss';
</style>
+21 -88
View File
@@ -8,6 +8,7 @@ import ProductIdentityStep from "@/components/molecules/ProductIdentityStep.vue"
import ProviderMappingStep from "@/components/molecules/ProviderMappingStep.vue";
import InventoryCopyStep from "@/components/molecules/InventoryCopyStep.vue";
import InventoryImagesStep from "@/components/molecules/InventoryImagesStep.vue";
import PricingReviewStep from "@/components/molecules/PricingReviewStep.vue";
import {
createAdminInventory,
createAdminProduct,
@@ -870,94 +871,26 @@ onMounted(load);
Record acquisition
</button>
</form>
<form id="workflow-pricing" class="showcase-panel" @submit.prevent="calculatePricing">
<h2 id="pricing-title">Calculate market value</h2>
<label class="fixture-label" for="pricing-inventory"
>Inventory copy</label
>
<select
id="pricing-inventory"
v-model="pricingInventoryId"
class="fixture-input"
required
>
<option value="" disabled>Select a copy</option>
<option v-for="item in inventory" :key="item.id" :value="item.id">
{{ item.id }}
</option>
</select>
<label class="fixture-label" for="pricing-provider">Provider</label>
<input
id="pricing-provider"
v-model="pricingProvider"
class="fixture-input"
required
/>
<label class="fixture-label" for="pricing-source"
>Source identifier</label
>
<input
id="pricing-source"
v-model="pricingSource"
class="fixture-input"
required
/>
<label class="fixture-label" for="pricing-price"
>Observed price (cents)</label
>
<input
id="pricing-price"
v-model="pricingPrice"
class="fixture-input"
type="number"
min="1"
required
/>
<button
class="button button--primary"
type="submit"
:disabled="isSaving"
>
Add observation and calculate
</button>
<button
class="button button--secondary"
type="button"
:disabled="isSaving"
@click="refreshPricing"
>
Refresh from provider<span v-if="refreshStatus">
({{ refreshStatus }})</span
>
</button>
<label class="fixture-label" for="override-price"
>Manual value (cents)</label
>
<input
id="override-price"
v-model="overridePrice"
class="fixture-input"
type="number"
min="0"
/>
<label class="fixture-label" for="override-reason"
>Override reason</label
>
<input
id="override-reason"
v-model="overrideReason"
class="fixture-input"
minlength="3"
/>
<button
class="button button--secondary"
type="button"
:disabled="isSaving"
@click="overridePricing"
>
Save manual value
</button>
</form>
<PricingReviewStep
:inventory-item-id="pricingInventoryId"
:provider="pricingProvider"
:source-identifier="pricingSource"
:observed-price="pricingPrice"
:override-price="overridePrice"
:override-reason="overrideReason"
:inventory="inventory"
:refresh-status="refreshStatus"
:is-saving="isSaving"
@update:inventory-item-id="pricingInventoryId = $event"
@update:provider="pricingProvider = $event"
@update:source-identifier="pricingSource = $event"
@update:observed-price="pricingPrice = $event"
@update:override-price="overridePrice = $event"
@update:override-reason="overrideReason = $event"
@calculate="calculatePricing"
@refresh="refreshPricing"
@override="overridePricing"
/>
</div>
<section class="admin-list" aria-labelledby="products-title">