panels-origin/web-panel/components/BudgetFicha.vue
2026-08-21 16:55:01 -05:00

60 lines
2.1 KiB
Vue

<template>
<div class="ficha">
<Message v-if="!item" severity="secondary" :closable="false">Seleccione una partida</Message>
<div v-else class="ficha-body">
<div class="ficha-head">
<Avatar icon="pi pi-list" shape="circle" />
<div>
<div class="toolbar-title">{{ item.code || "Sin clave" }}</div>
<div class="muted">{{ item.parent_path || item.chapter_name || "Sin capítulo" }}</div>
</div>
</div>
<div class="ficha-tags">
<Tag v-if="item.unit" :value="String(item.unit)" />
<Tag :value="money(item.amount)" severity="info" />
</div>
<p class="mt-3 ficha-description">{{ item.description }}</p>
<DataTable :value="rows" size="small" class="mt-3">
<Column field="label" header="Campo" />
<Column field="value" header="Dato" />
</DataTable>
<Button label="Editar partida" icon="pi pi-pencil" outlined class="w-full mt-3" @click="emit('edit')" />
</div>
</div>
</template>
<script setup lang="ts">
const props = defineProps<{ item?: Record<string, unknown> | null }>();
const emit = defineEmits<{ edit: [] }>();
const rows = computed(() => {
const item = props.item;
if (!item) return [];
return [
{ label: "Clave", value: item.code || "—" },
{ label: "Ruta", value: item.parent_path || item.chapter_name || "Sin capítulo" },
{ label: "Unidad", value: item.unit || "—" },
{ label: "Cantidad", value: qty(item.quantity) },
{ label: "Precio unitario", value: money(item.unit_price) },
{ label: "Importe", value: money(item.amount) },
];
});
function money(value: unknown) {
const amount = Number(value ?? 0);
if (Number.isNaN(amount)) return "—";
return new Intl.NumberFormat("es-MX", { style: "currency", currency: "MXN" }).format(amount);
}
function qty(value: unknown) {
const amount = Number(value ?? 0);
if (Number.isNaN(amount)) return "—";
return new Intl.NumberFormat("es-MX", { maximumFractionDigits: 4 }).format(amount);
}
</script>
<style scoped>
.ficha-description {
white-space: pre-wrap;
line-height: 1.45;
font-size: 12px;
}
</style>