207 lines
5.2 KiB
Vue
207 lines
5.2 KiB
Vue
<template>
|
|
<fournisseur-detail-template>
|
|
<template #button-return>
|
|
<div class="col-12">
|
|
<router-link
|
|
to="/fournisseurs"
|
|
class="btn btn-outline-secondary btn-sm mb-3"
|
|
>
|
|
<i class="fas fa-arrow-left me-2"></i>Retour aux fournisseurs
|
|
</router-link>
|
|
</div>
|
|
</template>
|
|
<template #loading-state>
|
|
<div v-if="isLoading" class="text-center p-5">
|
|
<div class="spinner-border text-primary" role="status">
|
|
<span class="visually-hidden">Chargement...</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #fournisseur-detail-sidebar>
|
|
<FournisseurDetailSidebar
|
|
:avatar-url="fournisseurAvatar"
|
|
:initials="getInitials(fournisseur.name)"
|
|
:fournisseur-name="fournisseur.name"
|
|
:fournisseur-type="fournisseur.type_label || 'Fournisseur'"
|
|
:contacts-count="filteredContactsCount"
|
|
:locations-count="locations.length"
|
|
:is-active="fournisseur.is_active"
|
|
:active-tab="activeTab"
|
|
@edit-avatar="triggerFileInput"
|
|
@change-tab="activeTab = $event"
|
|
/>
|
|
</template>
|
|
<template #file-input>
|
|
<input
|
|
:ref="fileInput"
|
|
type="file"
|
|
class="d-none"
|
|
accept="image/*"
|
|
@change="handleAvatarUpload"
|
|
/>
|
|
</template>
|
|
<template #fournisseur-detail-content>
|
|
<fournisseur-detail-content
|
|
:active-tab="activeTab"
|
|
:fournisseur="fournisseur"
|
|
:locations="locations"
|
|
:formatted-address="formatAddress(fournisseur)"
|
|
:fournisseur-id="fournisseur.id"
|
|
:contact-is-loading="contactLoading"
|
|
:location-is-loading="locationLoading"
|
|
@change-tab="activeTab = $event"
|
|
@updating-fournisseur="handleUpdateFournisseur"
|
|
@create-contact="handleAddContact"
|
|
@updating-contact="handleModifiedContact"
|
|
@contact-removed="handleRemovedContact"
|
|
@create-location="handleAddLocation"
|
|
@modify-location="handleModifyLocation"
|
|
@remove-location="handleRemoveLocation"
|
|
/>
|
|
</template>
|
|
</fournisseur-detail-template>
|
|
</template>
|
|
<script setup>
|
|
import { defineProps, defineEmits, ref, computed } from "vue";
|
|
import { useContactStore } from "@/stores/contactStore";
|
|
import FournisseurDetailTemplate from "@/components/templates/CRM/FournisseurDetailTemplate.vue";
|
|
import FournisseurDetailSidebar from "./fournisseur/FournisseurDetailSidebar.vue";
|
|
import FournisseurDetailContent from "./fournisseur/FournisseurDetailContent.vue";
|
|
import { RouterLink } from "vue-router";
|
|
|
|
const props = defineProps({
|
|
fournisseur: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
locations: {
|
|
type: Array,
|
|
required: false,
|
|
default: () => [],
|
|
},
|
|
isLoading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
contactIsLoading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
fournisseurAvatar: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
activeTab: {
|
|
type: String,
|
|
default: "overview",
|
|
},
|
|
fileInput: {
|
|
type: Object,
|
|
required: true,
|
|
},
|
|
contactLoading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
locationLoading: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
});
|
|
|
|
// Use contact store to get filtered contacts count
|
|
const contactStore = useContactStore();
|
|
|
|
const filteredContactsCount = computed(() => {
|
|
return contactStore.contacts.filter(
|
|
(contact) => contact.fournisseur_id === props.fournisseur.id
|
|
).length;
|
|
});
|
|
|
|
const localAvatar = ref(props.fournisseurAvatar);
|
|
|
|
const emit = defineEmits([
|
|
"updateTheFournisseur",
|
|
"handleFileInput",
|
|
"add-new-contact",
|
|
"updating-contact",
|
|
"contact-removed",
|
|
"add-new-location",
|
|
"modify-location",
|
|
"remove-location",
|
|
]);
|
|
|
|
const handleAvatarUpload = (event) => {
|
|
const file = event.target.files[0];
|
|
if (file) {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
localAvatar.value = e.target.result;
|
|
// TODO: Upload to server
|
|
console.log("Upload avatar to server");
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
};
|
|
|
|
const handleUpdateFournisseur = (updateData) => {
|
|
emit("updateTheFournisseur", updateData);
|
|
};
|
|
|
|
const inputFile = () => {
|
|
emit("handleFileInput");
|
|
};
|
|
|
|
const handleAddContact = (data) => {
|
|
emit("add-new-contact", data);
|
|
};
|
|
|
|
const handleModifiedContact = (modifiedContact) => {
|
|
emit("updating-contact", modifiedContact);
|
|
};
|
|
|
|
const handleRemovedContact = (contactId) => {
|
|
emit("contact-removed", contactId);
|
|
};
|
|
|
|
const handleAddLocation = (data) => {
|
|
emit("add-new-location", data);
|
|
};
|
|
|
|
const handleModifyLocation = (location) => {
|
|
emit("modify-location", location);
|
|
};
|
|
|
|
const handleRemoveLocation = (locationId) => {
|
|
emit("remove-location", locationId);
|
|
};
|
|
|
|
const getInitials = (name) => {
|
|
if (!name) return "?";
|
|
return name
|
|
.split(" ")
|
|
.map((word) => word[0])
|
|
.join("")
|
|
.toUpperCase()
|
|
.substring(0, 2);
|
|
};
|
|
|
|
const formatAddress = (fournisseur) => {
|
|
const parts = [
|
|
fournisseur.billing_address.line1,
|
|
fournisseur.billing_address.line2,
|
|
fournisseur.billing_address.postal_code,
|
|
fournisseur.billing_address.city,
|
|
fournisseur.billing_address.country_code,
|
|
].filter(Boolean);
|
|
|
|
return parts.length > 0 ? parts.join(", ") : "Aucune adresse renseignée";
|
|
};
|
|
|
|
const triggerFileInput = () => {
|
|
if (props.fileInput) {
|
|
props.fileInput.click();
|
|
}
|
|
};
|
|
</script>
|