| Numéro du ticket | Titre du ticket | |------------------|-----------------| | #203 | Réceptions — Parcours de pesée multi-étapes | ## Description de la PR [#203] Réceptions — Parcours de pesée multi-étapes ## Modification du .env ## Check list - [x] Pas de régression - [x] TU/TI/TF rédigée - [x] TU/TI/TF OK - [x] CHANGELOG modifié Reviewed-on: https://gitea.malio.fr/MALIO-DEV/Ferme/pulls/3 Reviewed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr> Co-authored-by: AUTIN Tristan <tristan@yuno.malio.fr> Co-committed-by: AUTIN Tristan <tristan@yuno.malio.fr>
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<form @submit.prevent="validate">
|
||||
<div class="grid grid-cols-1 items-start gap-8 mb-16">
|
||||
<h1 class="font-bold text-5xl uppercase">Réception</h1>
|
||||
<div class="flex flex-col">
|
||||
<label for="license-plate" class="font-bold uppercase text-xl mb-4">Immatriculation</label>
|
||||
<input
|
||||
id="license-plate"
|
||||
v-model="form.licensePlate"
|
||||
type="text"
|
||||
class="border-b border-black justify-self-start text-xl pb-[6px] uppercase"
|
||||
/>
|
||||
<p v-if="fieldErrors.licensePlate" class="text-red-600 text-sm">{{ fieldErrors.licensePlate }}</p>
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<label for="reception-date" class="font-bold uppercase text-xl mb-4">Date de reception</label>
|
||||
<input
|
||||
id="reception-date"
|
||||
v-model="form.receptionDate"
|
||||
type="date"
|
||||
class="border-b border-black justify-self-start text-xl pb-[6px] uppercase"
|
||||
/>
|
||||
<p v-if="fieldErrors.receptionDate" class="text-red-600 text-sm">{{ fieldErrors.receptionDate }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center">
|
||||
<button
|
||||
type="submit"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] justify-self-end"
|
||||
>Valider
|
||||
</button>
|
||||
</div>
|
||||
<p v-if="errorMessage" class="text-red-600 mt-4">{{ errorMessage }}</p>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { z } from 'zod'
|
||||
import { mapZodErrors } from '~/utils/zod-errors'
|
||||
import { useReceptionStore } from '~/stores/reception'
|
||||
|
||||
type ReceptionFormData = {
|
||||
licensePlate: string
|
||||
receptionDate: string
|
||||
}
|
||||
|
||||
const receptionStore = useReceptionStore()
|
||||
const { errorMessage: storeErrorMessage, current: storeReception } = storeToRefs(receptionStore)
|
||||
const form = reactive<ReceptionFormData>({
|
||||
licensePlate: '',
|
||||
receptionDate: ''
|
||||
})
|
||||
const fieldErrors = reactive<Partial<Record<keyof ReceptionFormData, string>>>({
|
||||
licensePlate: undefined,
|
||||
receptionDate: undefined
|
||||
})
|
||||
const errorMessage = computed(() => storeErrorMessage.value)
|
||||
const formSchema = z.object({
|
||||
licensePlate: z
|
||||
.string()
|
||||
.min(1, 'Immatriculation requise.')
|
||||
.max(20, 'Immatriculation trop longue (20 caracteres max).'),
|
||||
receptionDate: z
|
||||
.string()
|
||||
.min(1, 'Date de reception requise.')
|
||||
.regex(/^\d{4}-\d{2}-\d{2}$/, 'Date de reception invalide.')
|
||||
})
|
||||
|
||||
watch(
|
||||
storeReception,
|
||||
(reception) => {
|
||||
form.licensePlate = reception?.licensePlate ?? ''
|
||||
form.receptionDate = reception?.receptionDate ?? ''
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
async function validate() {
|
||||
if (!receptionStore.current) {
|
||||
return
|
||||
}
|
||||
|
||||
fieldErrors.licensePlate = undefined
|
||||
fieldErrors.receptionDate = undefined
|
||||
const normalizedLicensePlate = form.licensePlate.trim()
|
||||
const normalizedReceptionDate = form.receptionDate.trim()
|
||||
const result = formSchema.safeParse({
|
||||
licensePlate: normalizedLicensePlate,
|
||||
receptionDate: normalizedReceptionDate
|
||||
})
|
||||
if (!result.success) {
|
||||
const errors = mapZodErrors<ReceptionFormData>(result.error)
|
||||
fieldErrors.licensePlate = errors.licensePlate ?? 'Formulaire invalide.'
|
||||
fieldErrors.receptionDate = errors.receptionDate ?? 'Formulaire invalide.'
|
||||
return
|
||||
}
|
||||
|
||||
const nextStep = receptionStore.current.currentStep + 1
|
||||
await receptionStore.updateReception(receptionStore.current.id, {
|
||||
currentStep: nextStep,
|
||||
licensePlate: normalizedLicensePlate || null,
|
||||
receptionDate: normalizedReceptionDate || null
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center mt-[164px] gap-32">
|
||||
<div class="flex gap-8 items-center justify-center">
|
||||
<!--@TODO Prendre en compte que l'on peut aussi décharger de la marchandise-->
|
||||
<h1 class="text-3xl uppercase font-bold">Décharger les bêtes</h1>
|
||||
<UiLoadingDots />
|
||||
</div>
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="goNext"
|
||||
>Suivant</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useReceptionStore } from '~/stores/reception'
|
||||
|
||||
const receptionStore = useReceptionStore()
|
||||
|
||||
async function goNext() {
|
||||
if (!receptionStore.current) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextStep = receptionStore.current.currentStep + 1
|
||||
await receptionStore.updateReception(receptionStore.current.id, {
|
||||
currentStep: nextStep
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="flex justify-center">
|
||||
<div class="flex flex-col items-center w-[660px]">
|
||||
<h1 class="font-bold text-5xl uppercase">{{ title }}</h1>
|
||||
<!--@TODO Voir comment faire pour savoir si le pont-bascule et bien connecté + ajouter un icon comme sur la maquette-->
|
||||
<p class="text-primary-500 uppercase text-2xl mt-2">Pont-bascule connecté</p>
|
||||
<div
|
||||
v-if="errorMessage || showLoadingBox"
|
||||
class="w-full flex flex-col items-center justify-center border border-black h-[90px] mt-12 mb-[86px]">
|
||||
<p v-if="errorMessage" class="text-red-500">{{ errorMessage }}</p>
|
||||
<UiLoadingDots v-else />
|
||||
</div>
|
||||
<div v-else-if="displayWeight !== null" class="w-full">
|
||||
<div
|
||||
class="w-full flex flex-col items-center justify-center border border-black h-[90px] mt-12 mb-[25px] text-4xl">
|
||||
{{ displayWeight }} kg
|
||||
</div>
|
||||
<div class="grid grid-cols-2 border border-black text-center">
|
||||
<p class="border-r border-black py-3 text-4xl font-bold">DSD</p>
|
||||
<p class="py-3 text-4xl">{{ displayDsd }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-[54px]">
|
||||
<button
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px]"
|
||||
@click="fetchWeight"
|
||||
>{{ displayWeight !== null ? 'refaire une pesee' : 'peser' }}</button>
|
||||
<button
|
||||
v-if="displayWeight !== null"
|
||||
class="text-xl uppercase bg-primary-500 text-white h-[50px] w-[272px] ml-4"
|
||||
@click="saveWeight"
|
||||
>Valider la pesée</button>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useWeighing } from '~/composables/useWeighing'
|
||||
import { useReceptionStore } from '~/stores/reception'
|
||||
|
||||
const props = defineProps<{
|
||||
mode: 'gross' | 'tare'
|
||||
}>()
|
||||
|
||||
const receptionStore = useReceptionStore()
|
||||
const { current: storeReception, errorMessage: storeErrorMessage } = storeToRefs(receptionStore)
|
||||
const {
|
||||
displayWeight,
|
||||
displayDsd,
|
||||
title,
|
||||
errorMessage,
|
||||
showLoadingBox,
|
||||
fetchWeight,
|
||||
saveWeight
|
||||
} = useWeighing({
|
||||
mode: props.mode,
|
||||
reception: storeReception,
|
||||
updateReception: receptionStore.updateReception,
|
||||
loadReception: receptionStore.loadReception,
|
||||
storeError: storeErrorMessage
|
||||
})
|
||||
// @TODO Voir comment mettre en place la genération du bon, la validation de la reception et le dernier step
|
||||
|
||||
</script>
|
||||
Reference in New Issue
Block a user