feat: integrate BarcodeScanner into scan page (#22 #23)
Some checks failed
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
Pull Request Checks / Validate PR (pull_request) Has been cancelled
Some checks failed
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Deploy to Coolify / Run Tests (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Development (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Production (pull_request) Has been cancelled
Deploy to Coolify / Deploy to Test (pull_request) Has been cancelled
Pull Request Checks / Validate PR (pull_request) Has been cancelled
- Use ScanBarcodeScanner component in scan.vue - Add product lookup placeholder (Issue #24) - Add scan-to-add flow placeholder (Issue #25) - Handle barcode detection events - Show loading and error states - Allow rescan and manual entry Closes #22, #23
This commit is contained in:
@@ -2,25 +2,64 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1 class="text-3xl font-bold text-gray-900 mb-6">Scan Item</h1>
|
<h1 class="text-3xl font-bold text-gray-900 mb-6">Scan Item</h1>
|
||||||
|
|
||||||
<UCard>
|
<UCard v-if="!scannedBarcode" class="mb-6">
|
||||||
<div class="text-center py-12">
|
<ScanBarcodeScanner
|
||||||
<UIcon
|
@barcode-detected="handleBarcodeDetected"
|
||||||
name="i-heroicons-qr-code"
|
@manual-entry="showManualEntry = true"
|
||||||
class="w-16 h-16 text-gray-400 mx-auto mb-4"
|
|
||||||
/>
|
/>
|
||||||
<h3 class="text-lg font-semibold text-gray-900 mb-2">
|
</UCard>
|
||||||
Barcode Scanner
|
|
||||||
</h3>
|
<!-- Product Lookup Result -->
|
||||||
<p class="text-gray-600 mb-6">
|
<UCard v-if="productData" class="mb-6">
|
||||||
This feature will be implemented in Week 3.
|
<div class="space-y-4">
|
||||||
</p>
|
<div class="flex items-start gap-4">
|
||||||
|
<img
|
||||||
|
v-if="productData.image_url"
|
||||||
|
:src="productData.image_url"
|
||||||
|
:alt="productData.name"
|
||||||
|
class="w-24 h-24 object-cover rounded"
|
||||||
|
/>
|
||||||
|
<div class="flex-1">
|
||||||
|
<h3 class="text-xl font-bold mb-1">{{ productData.name }}</h3>
|
||||||
|
<p v-if="productData.brand" class="text-gray-600">{{ productData.brand }}</p>
|
||||||
|
<p class="text-sm text-gray-500 mt-2">Barcode: {{ scannedBarcode }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<UAlert
|
||||||
|
v-if="lookupError"
|
||||||
|
color="yellow"
|
||||||
|
icon="i-heroicons-exclamation-triangle"
|
||||||
|
title="Product not found"
|
||||||
|
:description="lookupError"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="flex gap-2">
|
||||||
<UButton
|
<UButton
|
||||||
to="/"
|
color="primary"
|
||||||
color="gray"
|
size="lg"
|
||||||
variant="soft"
|
icon="i-heroicons-plus"
|
||||||
|
class="flex-1"
|
||||||
|
@click="addToInventory"
|
||||||
>
|
>
|
||||||
Back to Inventory
|
Add to Inventory
|
||||||
</UButton>
|
</UButton>
|
||||||
|
<UButton
|
||||||
|
color="gray"
|
||||||
|
size="lg"
|
||||||
|
@click="resetScanner"
|
||||||
|
>
|
||||||
|
Scan Again
|
||||||
|
</UButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</UCard>
|
||||||
|
|
||||||
|
<!-- Loading State -->
|
||||||
|
<UCard v-if="isLookingUp">
|
||||||
|
<div class="text-center py-8">
|
||||||
|
<div class="inline-block animate-spin rounded-full h-12 w-12 border-b-2 border-primary-500 mb-4"></div>
|
||||||
|
<p class="text-gray-600">Looking up product...</p>
|
||||||
</div>
|
</div>
|
||||||
</UCard>
|
</UCard>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,4 +69,60 @@
|
|||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: 'default'
|
layout: 'default'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const scannedBarcode = ref<string | null>(null)
|
||||||
|
const productData = ref<any>(null)
|
||||||
|
const isLookingUp = ref(false)
|
||||||
|
const lookupError = ref<string | null>(null)
|
||||||
|
const showManualEntry = ref(false)
|
||||||
|
|
||||||
|
const handleBarcodeDetected = async (barcode: string) => {
|
||||||
|
scannedBarcode.value = barcode
|
||||||
|
lookupError.value = null
|
||||||
|
isLookingUp.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
// TODO: Implement product lookup via Edge Function (Issue #24)
|
||||||
|
// For now, create a basic product object
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000)) // Simulate API call
|
||||||
|
|
||||||
|
productData.value = {
|
||||||
|
name: `Product ${barcode}`,
|
||||||
|
brand: 'Unknown Brand',
|
||||||
|
barcode: barcode,
|
||||||
|
image_url: null
|
||||||
|
}
|
||||||
|
|
||||||
|
lookupError.value = 'Product lookup not yet implemented. Using default data.'
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Product lookup error:', error)
|
||||||
|
lookupError.value = 'Failed to look up product. You can still add it manually.'
|
||||||
|
productData.value = {
|
||||||
|
name: `Product ${barcode}`,
|
||||||
|
barcode: barcode
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
isLookingUp.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const addToInventory = () => {
|
||||||
|
// TODO: Implement scan-to-add flow (Issue #25)
|
||||||
|
// Navigate to add form with pre-filled data
|
||||||
|
navigateTo({
|
||||||
|
path: '/',
|
||||||
|
query: {
|
||||||
|
barcode: scannedBarcode.value,
|
||||||
|
name: productData.value?.name,
|
||||||
|
brand: productData.value?.brand
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const resetScanner = () => {
|
||||||
|
scannedBarcode.value = null
|
||||||
|
productData.value = null
|
||||||
|
lookupError.value = null
|
||||||
|
isLookingUp.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user