#49 fix: marcador de producto sin imagen visible en el mapa de provenance

This commit is contained in:
2026-08-16 04:10:39 -05:00
parent 6200fa7432
commit 18026617ce
7 changed files with 752 additions and 2 deletions

View File

@@ -0,0 +1,126 @@
<template>
<v-dialog
max-width="560"
:model-value="visible"
@update:model-value="onUpdateVisible"
>
<v-card v-if="relation">
<v-card-title class="d-flex align-center">
<v-icon class="mr-2" color="teal" icon="mdi-package-variant" />
<span class="font-weight-bold">{{ productName }}</span>
</v-card-title>
<v-divider />
<v-card-text>
<img
v-if="productImage"
alt="Imagen del producto"
class="provenance-image rounded-lg border mb-3"
:src="productImage"
>
<div
v-for="row in rows"
:key="row.kind"
class="d-flex align-start mb-3"
>
<v-icon class="mr-3" :color="row.color" :icon="row.icon" />
<div>
<div class="text-subtitle-2 font-weight-bold">
{{ row.label }}
</div>
<div class="text-body-1">
{{ row.name }}
</div>
<div
v-for="detail in row.details"
:key="detail.label"
class="text-body-2 text-medium-emphasis"
>
{{ detail.label }}: {{ detail.value }}
</div>
</div>
</div>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="close">Cerrar</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
relation: {
type: Object,
default: null,
},
product: {
type: Object,
default: null,
},
})
const emit = defineEmits(['update:visible'])
const ENTITY_INFO = {
supplier: { label: 'Proveedor', icon: 'mdi-truck', color: 'blue' },
organization: { label: 'Organización', icon: 'mdi-domain', color: 'orange' },
municipality: { label: 'Municipio', icon: 'mdi-map-marker', color: 'green' },
department: { label: 'Departamento', icon: 'mdi-map', color: 'indigo' },
country: { label: 'País', icon: 'mdi-earth', color: 'purple' },
}
const productName = computed(() => props.product?.name || 'Producto')
const productImage = computed(() => props.product?.catalogue_images?.[0] || null)
function entityDetails (kind, entity) {
const details = []
if (kind === 'supplier' || kind === 'organization') {
if (entity.description) details.push({ label: 'Descripción', value: entity.description })
if (entity.website) details.push({ label: 'Sitio web', value: entity.website })
if (entity.contact_email) details.push({ label: 'Correo', value: entity.contact_email })
if (entity.contact_phone) details.push({ label: 'Teléfono', value: entity.contact_phone })
}
return details
}
const rows = computed(() => {
const rel = props.relation || {}
return ['supplier', 'organization', 'municipality', 'department', 'country']
.filter(kind => rel[kind])
.map(kind => {
const info = ENTITY_INFO[kind]
return {
kind,
label: info.label,
icon: info.icon,
color: info.color,
name: rel[kind].name,
details: entityDetails(kind, rel[kind]),
}
})
})
function onUpdateVisible (value) {
emit('update:visible', value)
}
function close () {
emit('update:visible', false)
}
</script>
<style scoped>
.provenance-image {
display: block;
max-height: 220px;
max-width: 100%;
object-fit: contain;
}
</style>