feat: implement scan-to-add flow (#25)
Some checks failed
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
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
Some checks failed
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
Deploy to Coolify / Code Quality (pull_request) Has been cancelled
- Create useProductLookup composable - Integrate real product lookup in scan page - Add query parameter handling in index.vue - Pre-fill AddItemForm from scan data - Parse quantity and unit from product data - Include barcode and brand in notes Complete end-to-end scan workflow: 1. Scan barcode 2. Fetch from Open Food Facts 3. Navigate to inventory with data 4. Pre-filled add form 5. One-click add to inventory Closes #25
This commit is contained in:
@@ -131,6 +131,16 @@ const { addInventoryItem, addItemTags } = useInventory()
|
||||
const { getUnits } = useUnits()
|
||||
const { getTags } = useTags()
|
||||
|
||||
const props = defineProps<{
|
||||
initialData?: {
|
||||
barcode?: string
|
||||
name?: string
|
||||
brand?: string
|
||||
image_url?: string
|
||||
quantity?: string
|
||||
}
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: []
|
||||
added: [item: any]
|
||||
@@ -166,6 +176,40 @@ onMounted(async () => {
|
||||
if (defaultUnit) {
|
||||
form.unit_id = defaultUnit.id
|
||||
}
|
||||
|
||||
// Pre-fill from initial data (scan-to-add flow)
|
||||
if (props.initialData) {
|
||||
if (props.initialData.name) {
|
||||
form.name = props.initialData.name
|
||||
}
|
||||
|
||||
// Add brand to notes if available
|
||||
if (props.initialData.brand) {
|
||||
form.notes = `Brand: ${props.initialData.brand}`
|
||||
|
||||
if (props.initialData.barcode) {
|
||||
form.notes += `\nBarcode: ${props.initialData.barcode}`
|
||||
}
|
||||
} else if (props.initialData.barcode) {
|
||||
form.notes = `Barcode: ${props.initialData.barcode}`
|
||||
}
|
||||
|
||||
// Parse quantity if available (e.g., "750g")
|
||||
if (props.initialData.quantity) {
|
||||
const quantityMatch = props.initialData.quantity.match(/^([\d.]+)\s*([a-zA-Z]+)$/)
|
||||
if (quantityMatch) {
|
||||
form.quantity = parseFloat(quantityMatch[1])
|
||||
// Try to match unit
|
||||
const unitAbbr = quantityMatch[2].toLowerCase()
|
||||
const matchedUnit = units.value.find(u =>
|
||||
u.abbreviation.toLowerCase() === unitAbbr
|
||||
)
|
||||
if (matchedUnit) {
|
||||
form.unit_id = matchedUnit.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Unit options for select
|
||||
|
||||
Reference in New Issue
Block a user