feat(front) : tableau récap des bovins saisis avec suppression
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,7 +73,44 @@
|
||||
</UiButton>
|
||||
</form>
|
||||
|
||||
<div class="text-slate-400 italic mt-6">Tableau récap à venir</div>
|
||||
<UiDataTable
|
||||
v-model:page="recapPage"
|
||||
v-model:per-page="recapPerPage"
|
||||
:columns="recapColumns"
|
||||
:items="savedBovines"
|
||||
:total-items="savedBovines.length"
|
||||
:show-actions="true"
|
||||
>
|
||||
<template #cell-birthDate="{ item }">
|
||||
{{ formatDate(item.birthDate) }}
|
||||
</template>
|
||||
<template #cell-arrivalDate="{ item }">
|
||||
{{ formatDate(item.arrivalDate) }}
|
||||
</template>
|
||||
<template #cell-finalPrice="{ item }">
|
||||
{{ formatPrice(item.finalPrice) }}
|
||||
</template>
|
||||
<template #cell-pricePerKg="{ item }">
|
||||
{{ formatPrice(item.pricePerKg) }}
|
||||
</template>
|
||||
<template #cell-buildingCase.building.label="{ item }">
|
||||
{{ item.effectiveBuilding?.label ?? '—' }}
|
||||
</template>
|
||||
<template #cell-buildingCase.caseNumber="{ item }">
|
||||
{{ item.buildingCase?.caseNumber ?? '—' }}
|
||||
</template>
|
||||
<template #cell-bovineType.label="{ item }">
|
||||
{{ item.bovineType?.label ?? '—' }}
|
||||
</template>
|
||||
<template #actions="{ item }">
|
||||
<Icon
|
||||
name="mdi:delete-outline"
|
||||
size="24"
|
||||
class="cursor-pointer text-red-500 hover:text-red-700"
|
||||
@click="confirmDeleteBovine(item)"
|
||||
/>
|
||||
</template>
|
||||
</UiDataTable>
|
||||
|
||||
<div class="flex justify-end mt-8 mb-16">
|
||||
<UiButton
|
||||
@@ -107,6 +144,42 @@ const buildings = ref<BuildingData[]>([])
|
||||
const savedBovines = ref<BovineData[]>([])
|
||||
|
||||
const isAdding = ref(false)
|
||||
const recapPage = ref(1)
|
||||
const recapPerPage = ref(50)
|
||||
|
||||
const recapColumns = [
|
||||
{ key: 'nationalNumber', label: 'N° National', width: '110px' },
|
||||
{ key: 'workNumber', label: 'N° Travail', width: '90px' },
|
||||
{ key: 'bovineType.label', label: 'Race', width: '110px' },
|
||||
{ key: 'sex', label: 'Sexe', width: '60px' },
|
||||
{ key: 'birthDate', label: 'Né le', width: '90px' },
|
||||
{ key: 'receivedWeight', label: 'Poids', width: '70px' },
|
||||
{ key: 'arrivalDate', label: 'Entrée le', width: '90px' },
|
||||
{ key: 'pricePerKg', label: 'Prix/kg', width: '80px' },
|
||||
{ key: 'finalPrice', label: 'Prix total', width: '90px' },
|
||||
{ key: 'buildingCase.building.label', label: 'Bâtiment', width: '1fr' },
|
||||
{ key: 'buildingCase.caseNumber', label: 'Case', width: '60px' }
|
||||
]
|
||||
|
||||
const formatDate = (date: string | null | undefined) => {
|
||||
if (!date) return '—'
|
||||
const d = new Date(date.replace(' ', 'T'))
|
||||
if (isNaN(d.getTime())) return date
|
||||
return d.toLocaleDateString('fr-FR', { day: '2-digit', month: '2-digit', year: 'numeric' })
|
||||
}
|
||||
|
||||
const formatPrice = (price: number | null | undefined) => {
|
||||
if (price === null || price === undefined) return '—'
|
||||
return `${price.toLocaleString('fr-FR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })} €`
|
||||
}
|
||||
|
||||
const confirmDeleteBovine = async (bovine: BovineData) => {
|
||||
const confirmed = window.confirm(`Supprimer le bovin ${bovine.nationalNumber} ?`)
|
||||
if (!confirmed) return
|
||||
|
||||
await api.delete(`bovines/${bovine.id}`)
|
||||
await loadSavedBovines()
|
||||
}
|
||||
|
||||
interface FormState {
|
||||
nationalNumber: string
|
||||
|
||||
Reference in New Issue
Block a user