294 lines
9.8 KiB
Vue

<template>
<div class="container-fluid py-4">
<div class="row justify-content-center">
<div class="col-12 col-xl-8">
<div class="card">
<div class="card-header pb-0">
<div class="d-flex align-items-center justify-content-between">
<div>
<h5 class="mb-1">Ajouter une localisation</h5>
<p class="text-sm text-secondary mb-0">
Le client est obligatoire et au moins un champ d'adresse doit
etre renseigne.
</p>
</div>
</div>
</div>
<div class="card-body">
<div v-if="generalError" class="alert alert-danger" role="alert">
{{ generalError }}
</div>
<form @submit.prevent="handleSubmit">
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Client *</label>
<select
v-model="form.client_id"
class="form-select"
:class="{ 'is-invalid': fieldErrors.client_id }"
required
>
<option value="">Selectionner un client</option>
<option
v-for="client in clients"
:key="client.id"
:value="String(client.id)"
>
{{
client.company_name ||
client.name ||
`Client #${client.id}`
}}
</option>
</select>
<div v-if="fieldErrors.client_id" class="invalid-feedback">
{{ fieldErrors.client_id }}
</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Nom</label>
<input
v-model="form.name"
type="text"
class="form-control"
:class="{ 'is-invalid': fieldErrors.name }"
maxlength="191"
placeholder="Ex: Depot principal"
/>
<div v-if="fieldErrors.name" class="invalid-feedback">
{{ fieldErrors.name }}
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">Adresse ligne 1</label>
<input
v-model="form.address_line1"
type="text"
class="form-control"
:class="{ 'is-invalid': fieldErrors.address_line1 }"
maxlength="255"
/>
<div v-if="fieldErrors.address_line1" class="invalid-feedback">
{{ fieldErrors.address_line1 }}
</div>
</div>
<div class="mb-3">
<label class="form-label">Adresse ligne 2</label>
<input
v-model="form.address_line2"
type="text"
class="form-control"
:class="{ 'is-invalid': fieldErrors.address_line2 }"
maxlength="255"
/>
<div v-if="fieldErrors.address_line2" class="invalid-feedback">
{{ fieldErrors.address_line2 }}
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label">Code postal</label>
<input
v-model="form.postal_code"
type="text"
class="form-control"
:class="{ 'is-invalid': fieldErrors.postal_code }"
maxlength="20"
/>
<div v-if="fieldErrors.postal_code" class="invalid-feedback">
{{ fieldErrors.postal_code }}
</div>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Ville</label>
<input
v-model="form.city"
type="text"
class="form-control"
:class="{ 'is-invalid': fieldErrors.city }"
maxlength="191"
/>
<div v-if="fieldErrors.city" class="invalid-feedback">
{{ fieldErrors.city }}
</div>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Code pays</label>
<input
v-model="form.country_code"
type="text"
class="form-control text-uppercase"
:class="{ 'is-invalid': fieldErrors.country_code }"
maxlength="2"
/>
<div v-if="fieldErrors.country_code" class="invalid-feedback">
{{ fieldErrors.country_code }}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Latitude GPS</label>
<input
v-model="form.gps_lat"
type="number"
step="0.000001"
class="form-control"
:class="{ 'is-invalid': fieldErrors.gps_lat }"
/>
<div v-if="fieldErrors.gps_lat" class="invalid-feedback">
{{ fieldErrors.gps_lat }}
</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Longitude GPS</label>
<input
v-model="form.gps_lng"
type="number"
step="0.000001"
class="form-control"
:class="{ 'is-invalid': fieldErrors.gps_lng }"
/>
<div v-if="fieldErrors.gps_lng" class="invalid-feedback">
{{ fieldErrors.gps_lng }}
</div>
</div>
</div>
<div class="form-check form-switch mb-4">
<input
id="isDefault"
v-model="form.is_default"
class="form-check-input"
type="checkbox"
/>
<label class="form-check-label" for="isDefault">
Definir comme localisation par defaut
</label>
</div>
<div class="d-flex justify-content-end gap-2">
<button
type="button"
class="btn btn-outline-secondary mb-0"
:disabled="clientLocationStore.isLoading"
@click="router.push({ name: 'Localisation clients' })"
>
Annuler
</button>
<button
type="submit"
class="btn bg-gradient-primary mb-0"
:disabled="clientLocationStore.isLoading"
>
{{
clientLocationStore.isLoading ? "Creation..." : "Ajouter"
}}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { useRouter } from "vue-router";
import { useClientLocationStore } from "@/stores/clientLocation";
import { useClientStore } from "@/stores/clientStore";
import { useNotificationStore } from "@/stores/notification";
const router = useRouter();
const clientLocationStore = useClientLocationStore();
const clientStore = useClientStore();
const notificationStore = useNotificationStore();
const fieldErrors = ref({});
const form = reactive({
client_id: "",
name: "",
address_line1: "",
address_line2: "",
postal_code: "",
city: "",
country_code: "FR",
gps_lat: "",
gps_lng: "",
is_default: false,
});
const clients = computed(() => clientStore.clients || []);
const generalError = computed(() => {
const generalFieldError = fieldErrors.value.general;
if (Array.isArray(generalFieldError)) {
return generalFieldError[0];
}
return generalFieldError || clientLocationStore.error;
});
onMounted(async () => {
if (!clients.value.length) {
await clientStore.fetchClients({ page: 1, per_page: 100 });
}
});
const normalizePayload = () => ({
client_id: Number(form.client_id),
name: form.name || null,
address_line1: form.address_line1 || null,
address_line2: form.address_line2 || null,
postal_code: form.postal_code || null,
city: form.city || null,
country_code: (form.country_code || "FR").toUpperCase(),
gps_lat: form.gps_lat === "" ? null : Number(form.gps_lat),
gps_lng: form.gps_lng === "" ? null : Number(form.gps_lng),
is_default: form.is_default,
});
const handleSubmit = async () => {
fieldErrors.value = {};
clientLocationStore.clearError();
try {
await clientLocationStore.createClientLocation(normalizePayload());
notificationStore.created("Localisation");
setTimeout(() => {
router.push({ name: "Localisation clients" });
}, 1500);
} catch (error) {
if (error.response?.status === 422) {
fieldErrors.value = error.response.data.errors || {};
notificationStore.error(
"Erreur de validation",
"Veuillez corriger les erreurs dans le formulaire"
);
return;
}
const errorMessage =
error.response?.data?.message || "Impossible de creer la localisation";
notificationStore.error("Erreur", errorMessage);
}
};
</script>