Skip to content

Commit

Permalink
feat(price create form): move product scanning first (#102)
Browse files Browse the repository at this point in the history
* Price create form: move proof to the end. Seperate product & price

* Group price & proof

* Update icons
  • Loading branch information
raphodn authored Jan 7, 2024
1 parent 970a219 commit 38535f6
Showing 1 changed file with 63 additions and 58 deletions.
121 changes: 63 additions & 58 deletions src/views/AddPriceSingle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,17 @@
<v-form @submit.prevent="createPrice">
<v-row>

<!-- Step 1: proof -->
<!-- Step 1: product -->
<v-col cols="12" md="6" lg="4">
<v-card
title="Take a picture of the price tag"
subtitle="We need this for proof"
:prepend-icon="proofFormFilled ? 'mdi-image-check' : 'mdi-camera'"
title="Product details"
subtitle=""
:prepend-icon="productFormFilled ? 'mdi-database-check-outline' : 'mdi-database-outline'"
height="100%"
:style="proofFormFilled ? 'border: 1px solid #4CAF50' : 'border: 1px solid transparent'">
:style="productFormFilled ? 'border: 1px solid #4CAF50' : 'border: 1px solid transparent'">
<v-divider></v-divider>
<v-card-text>
<v-row>
<v-col>
<v-btn class="mb-2" size="small" prepend-icon="mdi-plus" @click.prevent="$refs.proof.click()" :loading="createProofLoading" :disabled="createProofLoading">Proof</v-btn>
<v-file-input
class="overflow-hidden d-none"
ref="proof"
:prepend-icon="proofFormFilled ? 'mdi-image-check' : 'mdi-camera'"
v-model="proofImage"
capture="environment"
accept="image/*"
@change="uploadProof"
@click:clear="clearProof"
:loading="createProofLoading">
</v-file-input>
<p v-if="proofFormFilled && !createProofLoading" class="text-green mb-2"><i>Proof uploaded!</i></p>
<p v-if="!proofFormFilled && !createProofLoading" class="text-red mb-2"><i>Upload a proof</i></p>
</v-col>
<v-col v-if="proofFormFilled">
<v-img :src="proofImagePreview" style="max-height:200px"></v-img>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-col>

<!-- Step 2: product & price -->
<v-col cols="12" md="6" lg="4">
<v-card
title="Product & price details"
subtitle="The most important :)"
:prepend-icon="productPriceFormFilled ? 'mdi-tag-check-outline' : 'mdi-tag-outline'"
height="100%"
:style="productPriceFormFilled ? 'border: 1px solid #4CAF50' : 'border: 1px solid transparent'">
<v-divider></v-divider>
<v-card-text>
<h3 class="mb-1">
Product
<h3 class="mb-2">
<v-item-group v-model="productMode" class="d-inline" mandatory>
<v-item v-for="pm in productModeList" :key="pm.key" :value="pm.key" v-slot="{ isSelected, toggle }">
<v-chip class="mr-1" @click="toggle">
Expand All @@ -61,14 +25,15 @@
</v-item-group>
</h3>
<v-sheet v-if="productMode === 'barcode'">
<v-btn class="mb-2" size="small" prepend-icon="mdi-plus" @click="showBarcodeScanner">Scan a barcode</v-btn>
<v-btn class="mb-2" size="small" prepend-icon="mdi-barcode-scan" @click="showBarcodeScanner">Scan a barcode</v-btn>
<v-text-field
v-if="dev"
:prepend-inner-icon="productBarcodeFormFilled ? 'mdi-barcode' : 'mdi-barcode-scan'"
v-model="addPriceSingleForm.product_code"
label="Product code"
type="text"
hint="EAN"
hide-details="auto"
@click:prepend="showBarcodeScanner"
></v-text-field>
<PriceCard v-if="product" class="mb-4" :product="product" :readonly="true" elevation="1"></PriceCard>
Expand Down Expand Up @@ -102,24 +67,60 @@
</div>
</v-sheet>
<p v-if="(productMode === 'barcode' && !productBarcodeFormFilled) || (productMode === 'category' && !productCategoryFormFilled)" class="text-red mb-2"><i>Set a product</i></p>
</v-card-text>
</v-card>
</v-col>

<!-- Step 2: price & proof -->
<v-col cols="12" md="6" lg="4">
<v-card
title="Price details"
subtitle="With a proof"
:prepend-icon="priceProofFormFilled ? 'mdi-tag-check-outline' : 'mdi-tag-outline'"
height="100%"
:style="priceProofFormFilled ? 'border: 1px solid #4CAF50' : 'border: 1px solid transparent'">
<v-divider></v-divider>
<v-card-text>
<h3 class="mb-1">Price <span v-if="productMode === 'category'">per kg</span></h3>
<v-row>
<v-col cols="6">
<v-text-field
v-model="addPriceSingleForm.price"
label="Price"
type="number"
hide-details="auto"
></v-text-field>
</v-col>
<v-col cols="6">
<v-autocomplete
v-model="addPriceSingleForm.currency"
label="Currency"
:items="currencyList"
hide-details="auto"
></v-autocomplete>
</v-col>
</v-row>
<v-row>
<v-col>
<v-btn class="mb-2" size="small" prepend-icon="mdi-camera" @click.prevent="$refs.proof.click()" :loading="createProofLoading" :disabled="createProofLoading">Proof</v-btn>
<v-file-input
class="overflow-hidden d-none"
ref="proof"
:prepend-icon="proofFormFilled ? 'mdi-image-check' : 'mdi-camera'"
v-model="proofImage"
capture="environment"
accept="image/*"
@change="uploadProof"
@click:clear="clearProof"
:loading="createProofLoading">
</v-file-input>
<p v-if="proofFormFilled && !createProofLoading" class="text-green mb-2"><i>Proof uploaded!</i></p>
<p v-if="!proofFormFilled && !createProofLoading" class="text-red mb-2"><i>Upload a proof</i></p>
</v-col>
<v-col v-if="proofFormFilled">
<v-img :src="proofImagePreview" style="max-height:200px"></v-img>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-col>
Expand All @@ -137,7 +138,6 @@
<h3 class="mb-1">
Location
</h3>
<v-btn class="mb-2" size="small" prepend-icon="mdi-plus" @click="showLocationSelector">Find</v-btn>
<v-chip
class="mb-2"
:style="isSelectedLocation(location) ? 'border: 1px solid #4CAF50' : 'border: 1px solid transparent'"
Expand All @@ -146,6 +146,7 @@
<v-icon start :icon="isSelectedLocation(location) ? 'mdi-checkbox-marked-circle' : 'mdi-history'"></v-icon>
{{ location.display_name }}
</v-chip>
<v-btn class="mb-2" size="small" prepend-icon="mdi-magnify" @click="showLocationSelector">Find</v-btn>
<p v-if="!locationFormFilled" class="text-red mb-2"><i>Select your location</i></p>

<h3 class="mt-4 mb-1">Date</h3>
Expand Down Expand Up @@ -223,7 +224,6 @@ export default {
dev: import.meta.env.DEV,
// price form
addPriceSingleForm: {
proof_id: null,
product_code: '',
category_tag: null,
origins_tags: '',
Expand All @@ -232,14 +232,10 @@ export default {
currency: null, // see initPriceSingleForm
location_osm_id: null,
location_osm_type: '',
date: new Date().toISOString().substr(0, 10)
date: new Date().toISOString().substr(0, 10),
proof_id: null,
},
createPriceLoading: false,
// proof data
proofImage: null,
proofImagePreview: null,
createProofLoading: false,
proofSuccessMessage: false,
// product data
product: null,
productModeList: [{key: 'barcode', value: 'Barcode', icon: 'mdi-barcode-scan'}, {key: 'category', value: 'Category', icon: 'mdi-basket-outline'}],
Expand All @@ -253,14 +249,15 @@ export default {
// location data
locationSelector: false,
locationSelectedDisplayName: '',
// proof data
proofImage: null,
proofImagePreview: null,
createProofLoading: false,
proofSuccessMessage: false,
}
},
computed: {
...mapStores(useAppStore),
proofFormFilled() {
let keys = ['proof_id']
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
},
productBarcodeFormFilled() {
let keys = ['product_code']
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
Expand All @@ -269,8 +266,16 @@ export default {
let keys = ['category_tag', 'origins_tags']
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
},
productPriceFormFilled() {
return (this.productBarcodeFormFilled || this.productCategoryFormFilled) && !!this.addPriceSingleForm.price && !!this.addPriceSingleForm.currency
productFormFilled() {
return this.productBarcodeFormFilled || this.productCategoryFormFilled
},
priceProofFormFilled() {
let keys = ['price', 'currency', 'proof_id']
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
},
proofFormFilled() {
let keys = ['proof_id']
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
},
recentLocations() {
return this.appStore.getRecentLocations(3)
Expand All @@ -284,7 +289,7 @@ export default {
return Object.keys(this.addPriceSingleForm).filter(k => keys.includes(k)).every(k => !!this.addPriceSingleForm[k])
},
formFilled() {
return this.proofFormFilled && this.productPriceFormFilled && this.locationDateFormFilled
return this.productFormFilled && this.priceProofFormFilled && this.locationDateFormFilled
},
},
mounted() {
Expand Down

0 comments on commit 38535f6

Please sign in to comment.